0

我将值从列表传递到数据表,然后将数据表作为表变量传递到存储过程。由于某种原因,表变量中的值没有正确传递。我运行了 sql profiler,发现所有的值都以 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 很昂贵,并且需要与插入一样长的时间。

我喜欢你可以在 IEnumerable <SqlDataRecord> 中调试。

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 回答