テーブル値パラメータのSQLを実行すると
「オブジェクト 'dbo.[テーブル値パラメータ変数]' には重複するキーを挿入できません。」のエラーが発生する現象の紹介です。
テーブル値パラメータのSQLを実行すると以下の例外が発生します。
英語では以下のメッセージとなります。
テーブル値パラメータに重複した値が挿入されています。
下図のフォームを作成します。
using Microsoft.Data.SqlClient;
using static System.ComponentModel.Design.ObjectSelectorEditor;
using System.Windows.Forms;
using System.Data;
namespace TableValuedParametersQuery
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<string> qList = new List<string>() { "X-XD05", "R-D400", "B-250", "NC-208", "R-D400" };
string constr = @"Data Source=192.168.64.48;Initial Catalog=iPentecSandBox;Connect Timeout=60;Persist Security Info=True;Encrypt=False;User ID=sa;Password=adelieC#8851SQL";
using (SqlConnection con = new SqlConnection(constr)) {
try {
con.Open();
string sqlstr = "SELECT * FROM ProductsF WHERE model IN(SELECT Model FROM @TVPParam)";
SqlCommand com = new SqlCommand(sqlstr, con);
// テーブル値型のデータを作成
DataTable table = new DataTable();
table.Columns.Add("Model", typeof(string));
foreach (string q in qList) {
table.Rows.Add(q);
}
// テーブル値パラメータを追加
SqlParameter tvpParam = com.Parameters.AddWithValue("@TVPParam", table);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.ModelList";
//exec
SqlDataReader sdr = com.ExecuteReader();
while (sdr.Read() == true) {
string model = (string)sdr["model"];
string name = (string)sdr["name"];
string category = (string)sdr["category"];
decimal price = (decimal)sdr["price"];
textBox1.Text += string.Format("{0} / {1} / {2} : {3:g} \r\n", model.Trim(), name.Trim(), category.Trim(), price);
}
}
finally {
con.Close();
}
}
}
}
}
プロジェクトを実行し、[button1]をクリックすると、以下のエラーが発生します。
テーブル値パラメータに挿入するリストの値を確認します。
R-D400
の値が2つあり、テーブル値パラメーターに重複した値を挿入しています。
List<string> qList = new List<string>() { "X-XD05", "R-D400", "B-250", "NC-208", "R-D400" };
以下に修正します。
List<string> qList = new List<string>() { "X-XD05", "R-D400", "B-250", "NC-208" };