我无法弄清楚这是否是可接受的操作。我需要从SQL Server 2008数据库中选择记录然后删除它们,所有这些都是ASP.NET代码中的单个事务。请注意,.NET代码必须能够检索首次选择的数据。
这样的东西:
SELECT * FROM [tbl] WHERE [id] > 6;
DELETE FROM [tbl] WHERE [id] > 6
我trying it使用SQL Fiddle,但如果我这样做:
SELECT * FROM [tbl]
我得到了完整的表格,好像没有删除任何内容。
编辑如下所述,这里是检索记录的完整.NET代码:
string strSQLStatement = "SELECT * FROM [tbl] WHERE [id] > 6;" +
"DELETE FROM [tbl] WHERE [id] > 6";
using (SqlCommand cmd = new SqlCommand(strSQLStatement, connectionString))
{
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while(rdr.Read())
{
//Read values
val0 = rdr.GetInt32(0);
val3 = rdr.GetInt32(3);
//etc.
}
}
}
答案 0 :(得分:22)
这将执行select和delete simultanious:
delete from [tbl] output deleted.* WHERE [id] > 6
答案 1 :(得分:1)
只要两个操作都在同一个事务中登记,就可以在同一个事务中进行选择和删除。
看看这篇文章 Transactions in .net
答案 2 :(得分:1)
与兼容的提供程序实现事务的“最简单”方法(SQL Server效果很好!)是使用TransactionScope。只需确保在打开连接之前创建范围,以便正确登记所有内容。
SelectStuff
和DeleteStuff
方法的内容并不重要 - 只需使用相同的连接,不要手动弄乱连接或事务,然后执行SQL操作最好的。
// Notes
// - Create scope OUTSIDE/BEFORE connection for automatic enlisting
// - Create only ONE connection inside to avoid DTC and "advanced behavior"
using (var ts = new TransactionScope())
using (var conn = CreateConnection()) {
// Make sure stuff selected is MATERIALIZED:
// If a LAZY type (Enumerable/Queryable) is returned and used later it
// may cause access to the connection outside of when it is valid!
// Use "ToList" as required to force materialization of such sequences.
var selectedStuff = SelectStuff(conn);
DeleteStuff(conn);
// Commit
ts.Complete();
// Know stuff is deleted here, and access selected stuff.
return selectedStuff;
}
答案 3 :(得分:0)
多个SQL语句的返回值是最后一个语句运行的结果,在本例中是DELETE
。 DELETE
没有返回任何行,因此val0
和val3
无法读取任何内容。
我可以在这里想到两个解决方案:
更改代码以明确启动交易,执行SELECT
,读取值,然后发出DELETE
或
SELECT
进入#temp
表,执行DELETE
,然后从SELECT
表执行#temp
,执行您需要的操作行,然后DROP
th。