Sql 将记录添加到实际表后,从暂存表中删除记录
我有一个asp.net程序,它将任务添加到我的暂存表中,并执行一个存储过程,该过程接受这些任务并将它们放在我的实际表中。我希望在添加记录后删除这些记录,因为我的暂存表将很快变大 这是我的存储过程代码Sql 将记录添加到实际表后,从暂存表中删除记录,sql,sql-server-2005,stored-procedures,Sql,Sql Server 2005,Stored Procedures,我有一个asp.net程序,它将任务添加到我的暂存表中,并执行一个存储过程,该过程接受这些任务并将它们放在我的实际表中。我希望在添加记录后删除这些记录,因为我的暂存表将很快变大 这是我的存储过程代码 INSERT INTO dashboardtasks SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compb
INSERT INTO dashboardtasks
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
FROM staggingtasks
WHERE NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE (staggingtasks.tour=dashboardtasks.tour and
staggingtasks.taskname=dashboardtasks.taskname and
staggingtasks.deptdate=dashboardtasks.deptdate and
staggingtasks.duedate=dashboardtasks.duedate and
staggingtasks.tourname=dashboardtasks.tourname
)
)
END
您可以运行
DELETE
语句来清除表
从myTable中删除
我的建议是使用begintry
和begincatch
这样,如果发生任何情况,您就不会从staging表中删除数据
BEGIN TRY
BEGIN TRAN
INSERT statement....
// All successful
DELETE statement...
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRAN
您可以运行
DELETE
语句来清除表
从myTable中删除
我的建议是使用begintry
和begincatch
这样,如果发生任何情况,您就不会从staging表中删除数据
BEGIN TRY
BEGIN TRAN
INSERT statement....
// All successful
DELETE statement...
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRAN
您可以在一个存储过程中运行多个查询,因此,除非我遗漏了一些内容,否则您应该能够添加这些内容
DELETE staggingtasks WHERE <any criteria you need>
删除暂存任务,其中
在插入查询之后…您可以在一个存储过程中运行多个查询,因此,除非我遗漏了什么,否则您应该能够添加
DELETE staggingtasks WHERE <any criteria you need>
删除暂存任务,其中
在INSERT查询之后…有一个delete语句,该语句的条件与INSERT相同,只是您现在使用的是EXISTS而不是NOT EXISTS 大概是这样的:
INSERT INTO dashboardtasks
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
FROM staggingtasks
WHERE NOT EXISTS
(
SELECT *
FROM dashboardtasks
WHERE (
staggingtasks.tour=dashboardtasks.tour and
staggingtasks.taskname=dashboardtasks.taskname and
staggingtasks.deptdate=dashboardtasks.deptdate and
staggingtasks.duedate=dashboardtasks.duedate and
staggingtasks.tourname=dashboardtasks.tourname
)
)
DELETE FROM staggingtasks
WHERE EXISTS
(
SELECT *
FROM dashboardtasks
WHERE (
staggingtasks.tour=dashboardtasks.tour and
staggingtasks.taskname=dashboardtasks.taskname and
staggingtasks.deptdate=dashboardtasks.deptdate and
staggingtasks.duedate=dashboardtasks.duedate and
staggingtasks.tourname=dashboardtasks.tourname
)
)
使用与insert相同条件的delete语句,但现在使用的是EXISTS而不是NOT EXISTS 大概是这样的:
INSERT INTO dashboardtasks
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
FROM staggingtasks
WHERE NOT EXISTS
(
SELECT *
FROM dashboardtasks
WHERE (
staggingtasks.tour=dashboardtasks.tour and
staggingtasks.taskname=dashboardtasks.taskname and
staggingtasks.deptdate=dashboardtasks.deptdate and
staggingtasks.duedate=dashboardtasks.duedate and
staggingtasks.tourname=dashboardtasks.tourname
)
)
DELETE FROM staggingtasks
WHERE EXISTS
(
SELECT *
FROM dashboardtasks
WHERE (
staggingtasks.tour=dashboardtasks.tour and
staggingtasks.taskname=dashboardtasks.taskname and
staggingtasks.deptdate=dashboardtasks.deptdate and
staggingtasks.duedate=dashboardtasks.duedate and
staggingtasks.tourname=dashboardtasks.tourname
)
)
可能您可以结合
OUTPUT
子句从暂存表中执行DELETE
。并将OUTPUT
子句的结果插入主表,以便在一个原子语句中完成这一切
OUTPUT deleted.* into dashboardtasks
然而,有一些因素可能使这种方法不可行
输出_表不能:
- 已启用在其上定义的触发器
- 参加一个项目的任何一方 外键约束李>
- 检查 约束或启用的规则
DELETE FROM staggingtasks
OUTPUT DELETED.[tour],
DELETED.tourname,
DELETED.[taskname],
DELETED.[deptdate],
DELETED.[tasktype],
DELETED.[desc],
DELETED.[duedate],
DELETED.[compdate],
DELETED.[comments],
DELETED.[agent],
DELETED.[compby],
DELETED.[graceperiod],
DELETED.completed,
DELETED.canceled
INTO dashboardtasks
WHERE NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE ( staggingtasks.tour = dashboardtasks.tour
and staggingtasks.taskname = dashboardtasks.taskname
and staggingtasks.deptdate = dashboardtasks.deptdate
and staggingtasks.duedate = dashboardtasks.duedate
and staggingtasks.tourname = dashboardtasks.tourname
))
可能您可以结合
OUTPUT
子句从暂存表中执行DELETE
。并将OUTPUT
子句的结果插入主表,以便在一个原子语句中完成这一切
OUTPUT deleted.* into dashboardtasks
然而,有一些因素可能使这种方法不可行
输出_表不能:
- 已启用在其上定义的触发器
- 参加一个项目的任何一方 外键约束李>
- 检查 约束或启用的规则
DELETE FROM staggingtasks
OUTPUT DELETED.[tour],
DELETED.tourname,
DELETED.[taskname],
DELETED.[deptdate],
DELETED.[tasktype],
DELETED.[desc],
DELETED.[duedate],
DELETED.[compdate],
DELETED.[comments],
DELETED.[agent],
DELETED.[compby],
DELETED.[graceperiod],
DELETED.completed,
DELETED.canceled
INTO dashboardtasks
WHERE NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE ( staggingtasks.tour = dashboardtasks.tour
and staggingtasks.taskname = dashboardtasks.taskname
and staggingtasks.deptdate = dashboardtasks.deptdate
and staggingtasks.duedate = dashboardtasks.duedate
and staggingtasks.tourname = dashboardtasks.tourname
))
请记住,删除将记录所有内容,因此,随着时间的推移,您的日志可能会变得太大。如果不关心暂存表中的数据,请在插入后尝试TRUNCATE命令:
TRUNCATE TABLE staggingtasks
正如其他人所说,您可能希望将其全部放在事务中以防万一。Truncate的优点是速度快,因为从表中清除的每条记录都不需要额外的日志记录。请记住,删除将记录所有内容,因此,随着时间的推移,日志可能会变得太大。如果不关心暂存表中的数据,请在插入后尝试TRUNCATE命令:
TRUNCATE TABLE staggingtasks
正如其他人所说,您可能希望将其全部放在事务中以防万一。Truncate的优点是它很快,因为从表中清除的每条记录都不需要额外的日志记录。如果事情可以同时发生(特别是如果可以在另一个进程发生时插入StagingTasks),那么现有的解决方案都不安全 您需要将数据插入临时表,然后从临时表中插入数据,然后根据临时表中的记录从临时表中删除数据。这样可以确保仅删除插入的记录,而不删除插入时添加的其他记录。当然,你应该像@Ardman所展示的那样,将所有这些放在一个事务中 此外,如果未指定要插入的字段,则不应执行插入操作。假设有人重新创建了表并重新排列了字段,那么insert将插入错误的字段(如果数据类型兼容)或失败
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
INTO #TasksToInsert
FROM staggingtasks
WHERE NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE (staggingtasks.tour=dashboardtasks.tour
AND staggingtasks.taskname=dashboardtasks.taskname
AND staggingtasks.deptdate=dashboardtasks.deptdate
AND staggingtasks.duedate=dashboardtasks.duedate
AND staggingtasks.tourname=dashboardtasks.tourname)
)
INSERT INTO dashboardtasks ([tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled )
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
FROM #TasksToInsert
DELETE FROM staggingtasks
WHERE EXISTS (SELECT *
FROM #TasksToInsert
WHERE (staggingtasks.tour=#TasksToInsert.tour
AND staggingtasks.taskname=#TasksToInsert.taskname
AND staggingtasks.deptdate=#TasksToInsert.deptdate
AND staggingtasks.duedate=#TasksToInsert.duedate
AND staggingtasks.tourname=#TasksToInsert.tourname)
)
如果这还没有投入生产,请修复StagingTasks的拼写错误。否则,它将困扰您的开发人员多年!我也会考虑在DASBOBOART任务表中添加一个代理键,因为多字段PK可能会导致性能问题,如果有子表,较小的INT键就不会出现问题。但是仍然要在自然键上创建一个唯一的索引。如果事情可以同时发生(特别是如果可以在另一个进程发生时插入stagingTasks),那么现有的解决方案都不安全 您需要将数据插入临时表,然后从临时表中插入数据,然后根据临时表中的记录从临时表中删除数据。这样可以确保仅删除插入的记录,而不删除插入时添加的其他记录。当然,你应该像@Ardman所展示的那样,将所有这些放在一个事务中 此外,如果未指定要插入的字段,则不应执行插入操作。假设有人重新创建了表并重新排列了字段,那么insert将插入错误的字段(如果数据类型兼容)或失败
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
INTO #TasksToInsert
FROM staggingtasks
WHERE NOT EXISTS(SELECT *
FROM dashboardtasks
WHERE (staggingtasks.tour=dashboardtasks.tour
AND staggingtasks.taskname=dashboardtasks.taskname
AND staggingtasks.deptdate=dashboardtasks.deptdate
AND staggingtasks.duedate=dashboardtasks.duedate
AND staggingtasks.tourname=dashboardtasks.tourname)
)
INSERT INTO dashboardtasks ([tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled )
SELECT [tour], tourname, [taskname], [deptdate], [tasktype], [desc], [duedate], [compdate], [comments], [agent], [compby], [graceperiod], completed , canceled
FROM #TasksToInsert
DELETE FROM staggingtasks
WHERE EXISTS (SELECT *
FROM #TasksToInsert
WHERE (staggingtasks.tour=#TasksToInsert.tour
AND staggingtasks.taskname=#TasksToInsert.taskname
AND staggingtasks.deptdate=#TasksToInsert.deptdate
AND staggingtasks.duedate=#TasksToInsert.duedate
AND staggingtasks.tourname=#TasksToInsert.tourname)
)
如果这还没有投入生产,请修复StagingTasks的拼写错误。否则,它将困扰您的开发人员多年!我也会考虑把DasBoAdWork表中的代理键放进多字段PK,就像你可能引起PE一样。