Sql 确保在触发删除之前成功插入

Sql 确保在触发删除之前成功插入,sql,sql-server,Sql,Sql Server,我目前正在对数据库进行归档,我想出了一个简单的方法。但是,执行脚本可能会出错。导致插入未成功执行但删除失败的情况。这意味着在将记录插入存档之前,我会从生产中删除记录。是否有办法确保除非insert成功运行,否则不会执行delete语句 INSERT INTO [archive].[dbo].[Table] SELECT * FROM [Production].[dbo].[Table] WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME()) D

我目前正在对数据库进行归档,我想出了一个简单的方法。但是,执行脚本可能会出错。导致插入未成功执行但删除失败的情况。这意味着在将记录插入存档之前,我会从生产中删除记录。是否有办法确保除非insert成功运行,否则不会执行delete语句

INSERT INTO [archive].[dbo].[Table]
SELECT *
FROM [Production].[dbo].[Table]
WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME()) 

DELETE FROM [Production].[dbo].[table]
WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME())
插入[archive].[dbo].[Table]
挑选*
来自[Production].[dbo].[Table]
其中时间戳<日期添加(年份,-2,SYSDATETIME())
从[Production].[dbo].[table]中删除
其中时间戳<日期添加(年份,-2,SYSDATETIME())

通常,您会创建一个事务,将操作变成一个更新

BEGIN TRAN

BEGIN TRY
    INSERT INTO [archive].[dbo].[Table] 
    SELECT * FROM [Production].[dbo].[Table] WHERE TimeStamp < 
             DATEADD(year,-2,SYSDATETIME())

    DELETE FROM [Production].[dbo].[table] 
    WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME())

    COMMIT
END TRY
BEGIN CATCH
   ROLLBACK
END CATCH

祝你好运

通常,你会创建一个事务,将操作变成一个更新

BEGIN TRAN

BEGIN TRY
    INSERT INTO [archive].[dbo].[Table] 
    SELECT * FROM [Production].[dbo].[Table] WHERE TimeStamp < 
             DATEADD(year,-2,SYSDATETIME())

    DELETE FROM [Production].[dbo].[table] 
    WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME())

    COMMIT
END TRY
BEGIN CATCH
   ROLLBACK
END CATCH

祝您好运

作为明确事务的替代方案,您可以在
删除
上指定
输出
子句,以作为单个自动提交事务执行操作。这将确保所有或无行为

DELETE [Production].[dbo].[Table]
OUTPUT DELETED.*   
INTO [archive].[dbo].[Table]
WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME());
删除[Production].[dbo].[Table]
输出已删除。*
进入[存档].[dbo].[表]
其中TimeStamp

此外,考虑一个显式列列表,而不是<代码> */COD> .< /P> < P>作为一个显式事务的替代,可以在<代码> Dele> <代码>中指定<代码>输出“/Cuth>”子句,以将该操作作为一个自动提交事务执行。这将确保所有或无行为

DELETE [Production].[dbo].[Table]
OUTPUT DELETED.*   
INTO [archive].[dbo].[Table]
WHERE TimeStamp < DATEADD(year,-2,SYSDATETIME());
删除[Production].[dbo].[Table]
输出已删除。*
进入[存档].[dbo].[表]
其中TimeStamp

也可以考虑一个显式列列表,而不是<代码> *>代码> ./p>可以在INSERT语句之后放置一个提交语句,然后使用DeleT。是否使用PHP?不,不使用PHP可以帮助您在INSERT语句之后放置提交语句,然后使用DeleT。是否使用PHP?否,如果@TRANCOUNT>0回滚,我建议使用catch block
;投掷
以引发错误,而不是以静默方式忽略它。指定
设置XACT\u ABORT ON也是一个好主意
确保在客户端查询超时时立即回滚explict事务,因为在这种情况下不会执行catch块代码。完全同意,不应忽略BEGIN catch中的错误。它是如何被捕获的是开发者需要考虑的…感谢您的评论我建议捕获块
IF@@TRANCOUNT>0回滚;投掷
以引发错误,而不是以静默方式忽略它。指定
设置XACT\u ABORT ON也是一个好主意
确保在客户端查询超时时立即回滚explict事务,因为在这种情况下不会执行catch块代码。完全同意,不应忽略BEGIN catch中的错误。它是如何被捕获的是开发者需要考虑的…谢谢你的评论