通过 CLR 的 SQLDatareader 没有以正确的方式返回 SQL 消息
Posted
技术标签:
【中文标题】通过 CLR 的 SQLDatareader 没有以正确的方式返回 SQL 消息【英文标题】:SQLDatareader via CLR not returning SQL Message right way 【发布时间】:2010-07-28 19:09:02 【问题描述】:我通过CLR执行下面的代码,消息没有打印到SQL Server有什么原因,是否需要等到存储过程返回所有行(大约有70亿行要返回)
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "spCommand_Select_Rows_For_Delete";
cmd.CommandTimeout = 41600;
SqlDataReader reader = cmd.ExecuteReader();
try
string strSQL = "";
SqlContext.Pipe.Send(DateTime.Now.ToString() + " - Started working with ProductTable");
while (reader.Read())
strSQL = "DELETE FROM ProductTable WHERE ProductId = " + reader["ProductId"].ToString();
SqlCommand cmdDelete = new SqlCommand(strSQL, conn);
cmdDelete.Connection = conn;
cmdDelete.CommandTimeout = 20800;
cmdDelete.ExecuteNonQuery();
SqlContext.Pipe.Send(DateTime.Now.ToString() + " - Completed working with ProductTable");
finally
// Always call Close when done reading.
reader.Close();
我的存储过程:
SELECT ProductId FROM ProductTable
WHERE ProductInfoId IN
(
SELECT ProductInfoId from DeletedProducts
)
【问题讨论】:
70 亿行来自存储过程?因此,您要一个接一个从较大的行中删除 70 亿行? 哇,这就是 RBAR 中有 A 的原因。 【参考方案1】:以下是使用基于集合的良好操作删除 70 亿行的方法。您不会abuse在 CLR 中遍历数据读取器。
SELECT 'Starting'
WHILE ROWCOUNT <> 0
DELETE TOP (1000000) P
FROM ProductTable P
WHERE EXISTS (
SELECT * from DeletedProducts DP WHERE P.ProductInfoId = DP.ProductInfoId
)
更多,请看这个问题Bulk DELETE on SQL Server 2008
但是要回答您的问题,是的,SQL Server 不会立即PRINT(您正在做的事情)
【讨论】:
这是否会在它到达顶部 (1000000) 时立即跳出表格,而不是继续扫描整个表格? @RPS:会因为WHILE分批删除1000000个(现在我修正了错字) 这不会导致 SQL LOG 变得非常大吗? 逐个删除 70 亿行,或者分 7000 批删除几乎无关紧要 我想删除很多行,但我不想占用大量磁盘空间,也不想花费数周时间来删除。【参考方案2】:您可能可以使用带有RAISERROR WITH NOWAIT 的 SqlContext.Pipe.ExecuteAndSend 来对消息执行您想要的操作。
但我同意 gbn 关于批量删除不需要 CLR 的回答。
【讨论】:
以上是关于通过 CLR 的 SQLDatareader 没有以正确的方式返回 SQL 消息的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法将任务并行库(TPL)与 SQLDataReader 一起使用?
将 DataTableReader 转换为 SqlDataReader