我将值从列表传递到数据表,然后将数据表作为表变量传递给存储过程。由于某种原因,值未在Table变量中正确传递。 我运行了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
答案 0 :(得分:1)
创建数据表是不必要的开销。
如果您有列表,可以通过实施IEnumerable <SqlDataRecord
&gt;直接使用它
我总是按照IEnumerable.GetEnumerator()中的PK排序,以保持索引碎片化。
asynch创建lastDocFTSinX的原因很昂贵,并且需要与插入一样长。
我喜欢你可以在IEnumerable <SqlDataRecord
&gt;中调试。
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());
}
}