.net 我能在一段时间内从一个SQLServer表中删除记录吗?

.net 我能在一段时间内从一个SQLServer表中删除记录吗?,.net,sql-server,ado.net,sqldatareader,.net,Sql Server,Ado.net,Sqldatareader,我正在尝试使用SQL数据读取器将记录从一个表移动到存档表中。我希望逐个记录进行传输(而不是大量插入和删除),以便在发生错误时,丢失的数据量最小(并且必须从备份中恢复) 我的问题是,如果我在读取记录后删除记录,SQL reader会工作吗?这是迄今为止最简单、最直接的方法来做我正在尝试做的事情。它会出现意外错误吗 While myReader.Read // select * from tableA where older than 1 year record insert the rec

我正在尝试使用SQL数据读取器将记录从一个表移动到存档表中。我希望逐个记录进行传输(而不是大量插入和删除),以便在发生错误时,丢失的数据量最小(并且必须从备份中恢复)

我的问题是,如果我在读取记录后删除记录,SQL reader会工作吗?这是迄今为止最简单、最直接的方法来做我正在尝试做的事情。它会出现意外错误吗

While myReader.Read // select * from tableA where older than 1 year record
    insert the record into tableA_archive
    delete the record from tableA   
loop
这似乎有点类似于在循环中修改列表,我知道这会在.net中引起各种各样的麻烦

for aItem in listA
   if aItem fits criteria, send to list B and delete from listA
next

在读卡器读取时,是否有任何理由不修改基础表?例如,读取器是否使用某些索引来达到记录,如果我开始删除循环中间的记录,可能会发生偏移?

,您应该在事务中执行。这也是SP的一个很好的候选者,即使您也可以在代码中这样做。您必须找出一个导致相当多行的条件(不是1,但可能是100、1000或10000)。实验并找出在合理的时间(可能是几秒钟)内,一条语句可以插入和删除多少条语句

某些条件可能是日期范围(例如一天、一小时等)

然后在循环中运行此过程,更改SomeCondition,直到没有要备份的内容。因为这是在一个事务中,所以insert和delete要么成功,要么失败


无论您想在一个事务中删除多少个,如果您担心一致性,您必须在事务中进行删除。

您应该花一些时间阅读,特别是可重复读取

在SQL Server中,select语句(支持读卡器)在读取提交隔离状态下执行(默认情况下),这意味着您的delete命令将能够在读取行后删除行,但在select语句执行时,读卡器读取的行集不能由delete语句修改


无论如何,将数据从一个表移动到另一个表通常应该使用SQL,而不是.NET。

有几种方法,首先您必须了解什么是事务隔离 在SQL server中,以及何时需要使用它


在您的情况下,似乎您正在将历史数据移动到另一个表中,因此在事务范围内使用SQL存储过程(带有回滚转换)是值得的。

您应该避免将行一直传输到客户端,而只是将它们重新上传回服务器。相反,可以这样做(在同一事务中):

甚至是特定于MS SQL Server的:

DELETE FROM OLD_TABLE OUTPUT DELETED.* INTO NEW_TABLE WHERE condition;
(所有条件相同)


如果愿意,您甚至可以从.NET代码中执行这些语句,并且仍然保留下载所有行的好处。

您应该为此技术指定正确的隔离级别(可重复读取)。默认值(READ COMMITTED)可能会导致SELECT语句检索到与DELETE语句不同的行。为什么不将
DELETE FROM tableA OUTPUT deleted.*放入tableA_归档文件,其中Dt@MartinSmith nice,不知道DELETE-INTO语法。一致认为最好的方法是编写一个使用事务语句的SQL server存储过程。因此,在事务中基本上需要两条语句:将旧记录插入存档,从非存档中删除旧记录。transaction语句将确保这两条语句都执行,或者两条语句都不执行。如果在事务处理过程中遇到错误,则不会发生插入/删除操作。正确吗?另外,似乎您需要捕获事务中的错误并指定回滚,否则它可能会继续运行@MartinSmith,这应该是一个答案。感谢Branko(和@MartinSmith)。沿着这些路线的查询在测试环境中运行良好。然而,我想安全地运行它。假设它只是一条语句,我应该在事务语句中运行它吗?SQL server是否会将其回滚,以便在遇到错误时永远不会运行?@akh2103任何自尊的DBMS(包括MS SQL server)都不会允许您执行事务之外的任何操作。即使没有显式启动事务,事务也会隐式启动(如果出现问题,ADO.NET提供程序甚至会自动回滚)。因此,是的,即使没有显式地将其包装到事务中,
DELETE FROM OLD_TABLE OUTPUT…
也会得到“all or nothing”行为。
INSERT INTO NEW_TABLE SELECT * FROM OLD_TABLE WHERE condititon;
DELETE FROM OLD_TABLE WHERE condititon;
DELETE FROM OLD_TABLE OUTPUT DELETED.* INTO NEW_TABLE WHERE condition;