0

リストからデータテーブルに値を渡し、データテーブルをテーブル変数としてストアドプロシージャに渡します。何らかの理由で、値がテーブル変数に正しく渡されません。SQL プロファイラーを実行したところ、すべての値が NULL として入っていることがわかりました

        DataTable dbRk1 = new DataTable("dbRk1");
        dbRk1.Columns.Add("val1", typeof(String));
        dbRk1.Columns.Add("val2", typeof(DateTime));
        dbRk1.Columns.Add("val2", typeof(Int64));
        dbRk1.Columns.Add("val3", typeof(Int32));
        dbRk1.Columns.Add("val4", typeof(Int64));
        dbRk1.Columns.Add("val5", typeof(Int32));
        dbRk1.Columns.Add("val5", typeof(DateTime));

        drk.x.ForEach(x => dbRk1.Rows.Add(x));
        DataTable table = new DataTable();
        SqlConnection conn = null;
        using (conn =new connection...)
        {
            SqlCommand cmd = new SqlCommand("[proc]", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@TableVariable", dbRk1);
    cmd.ExecuteNonQuery();

}

     Alter PROCEDURE [dbo].[proc]
    (
        @TableVar [dbo].[TableVar] READONLY
    )
    AS
BEGIN
Set nocount on
Declare @MYID INT
Declare @SOMEDate DateTime
Declare @NEWDate Date


select @MYID = some_id,
@SOMEDate = convert(date, db_some_date) from tbl_some
where someval = (select tb.val1 from @TableVar as tb);


Merge DeviceBillCycle as target
  using (Select x.val1, x.val2, x.val3,x.val4,
                        x.val5,x.val6, x.val7 from @TableVar as x)
  as Source

  on val_id = @MYID
  when matched and  @MYID !=NULL then

 update set      val1= Source.[val1],
                  val2=Source.[val2],
                  val3=Source.[val3],
                  val4=Source.[val4],
                  val5=Source.[val5],
                  val6=Source.[val6]

  when not matched and @MYID !=NULL then  
   insert  
   values (Source.[val1],
           Source.[val2],
           Source.[val3],
               Source.[val4],
               Source.[val5],
               Source.[val6],
               Source.[val7],
               @MYID
      )      ;
end 
4

1 に答える 1

1

データテーブルの作成は不要なオーバーヘッドです。

リストがある場合は、IEnumerable <SqlDataRecord> を実装することで直接使用できます。
私は常に IEnumerable.GetEnumerator() の PK でソートして、インデックスの断片化を抑えています。
非同期の理由は、lastDocFTSinX の作成が高価であり、挿入と同じくらい時間がかかるためです。

<SqlDataRecordIEnumerable >でデバッグできるのが気に入っています。

SqlConnection sqlConnFTSindexInX = new SqlConnection(builder.ToString());
sqlConnFTSindexInX.Open();
SqlCommand sqlCmdFTSindexInX = new SqlCommand("InsertFTSindexInXTablock_TVP", sqlConnFTSindexInX);
sqlCmdFTSindexInX.CommandType = CommandType.StoredProcedure;
AsyncCallback callbackFTSindexInX = new AsyncCallback(HandleCallbackFTSindexInX);
SqlParameter tvpParamFTSindexInX = sqlCmdFTSindexInX.Parameters.Add("@ItemTVP", SqlDbType.Structured);
tvpParamFTSindexInX.Direction = ParameterDirection.Input;

次のグループはループ中です

while (isExecutingFTSindexInX)
{
    Thread.Sleep(10);
}    
docFTSinXsCollection = new DocFTSinXsCollection(lastSID, lastDocFTSinX);
tvpParamFTSindexInX.Value = docFTSinXsCollection;
sqlCmdFTSindexInX.BeginExecuteNonQuery(callbackFTSindexInX, sqlCmdFTSindexInX);
// the callback will set isExecutingFTSindexInX = false;


    public class DocFTSinXsCollection : List<DocFTSinX>, IEnumerable<SqlDataRecord>
    {
        // used by TVP for fast insert
        private int sID;
        private IEnumerable<DocFTSinX> docFTSinXs;
        IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
        {
            var sdr = new SqlDataRecord(
            new SqlMetaData("wordID1", System.Data.SqlDbType.Int),
            new SqlMetaData("wordID2", System.Data.SqlDbType.Int),
            new SqlMetaData("sID", System.Data.SqlDbType.Int),
            new SqlMetaData("Delta", System.Data.SqlDbType.Int));
            foreach (DocFTSinX oh in docFTSinXs.OrderBy(x => x.Word1).ThenBy(x => x.Word2))
            {
                sdr.SetInt32(0, oh.Word1);
                sdr.SetInt32(1, oh.Word2);
                sdr.SetInt32(2, sID);
                sdr.SetInt32(3, (Int32)oh.Delta);
                yield return sdr;
            }
        }

        public DocFTSinXsCollection(int SID, IEnumerable<DocFTSinX> DocFTSinXs)
        {
            sID = SID;
            docFTSinXs = DocFTSinXs;
            //Debug.WriteLine("DocFTSinXsCollection DocFTSinXs " + DocFTSinXs.Count().ToString());
        }
    }
于 2012-09-10T19:52:32.903 に答える