現象
引数として 制約 が設定されているテーブル値パラメーター (tvp) を取得する、次のような transact-sql ストアドプロシージャがあるとします。
create type TestTvpType as table
(
id int primary key, -- UNIQUE will also do the trick
data int
);
go
create procedure TestTvpProc @tvp TestTvpType readonly
as
begin
select * from @tvp;
end;
go
このプロシージャが SQLCLR ストアドプロシージャから呼び出され、引数に対する 制約 に違反している場合、"制約違反" というエラーメッセージが表示されることを予期していたときに、システムアサートが誤って表示されることがあります。
ストアドプロシージャの制約違反を生成する SQLCLR プロシージャの例を次に示します。
[SqlProcedure]
public static void ClrProcCallingTsqlProcWithTvpArgument(out int sum)
{
using (SqlConnection connection = new SqlConnection("context connection=true"))
{
sum = 0;
DataTable myDataTable = new DataTable("TestTvpType");
myDataTable.Columns.Add("id", typeof(Int32));
myDataTable.Columns.Add("data", typeof(Int32));
// Populate the TVP so it will trigger a PRIMARY KEY VIOLATION error
myDataTable.Rows.Add(1, 1000);
myDataTable.Rows.Add(1, 2000);
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@tvp";
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.Value = myDataTable;
SqlCommand command = new SqlCommand("TestTvpProc", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(parameter);
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
…;
}
}
}
}
解決方法
この問題は、SQL Server の次の累積的な更新プログラムで修正されています。
SQL Server 2016 RTM の累積更新プログラム5
SQL Server 2016 SP1 の累積更新プログラム2
SQL Server 2014 Service Pack 2 の累積更新プログラム4
注この更新プログラムでは、正しい "制約違反" というエラーメッセージが表示されます。
SQL Server 用の新しい累積的な更新プログラムには、以前の累積的な更新プログラムに含まれていたすべての修正プログラムとセキュリティの修正が含まれています。 SQL Server の最新の累積的な更新プログラムを確認します。
状態
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。
関連情報
Microsoft でソフトウェアの更新について説明する 用語 について説明します。