我有一个asp.net程序,它将任务添加到我的临时表并执行一个存储过程,它接受这些任务并将它们放在我的实际表中,我想在添加它们之后删除它们,因为我的暂存桌子会快得太快。
这是我的存储过程代码
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
答案 0 :(得分:3)
您可以从临时表中结合DELETE
子句执行OUTPUT
。和INSERT
OUTPUT
子句的结果进入主表,在一个原子语句中完成所有这些。
OUTPUT deleted.* into dashboardtasks
虽然有some restrictions listed in BOL可能会使这种方法变得不可行。
output_table不能:
查询的完整语法...
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
))
答案 1 :(得分:2)
使用与插入标准相同的删除声明,但现在使用 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
)
)
答案 2 :(得分:2)
请记住,删除会记录所有内容,以便日志可能会变得太大。如果您不关心临时表中的数据,请在插入后尝试TRUNCATE命令:
TRUNCATE TABLE staggingtasks
正如其他人所说的那样,您可能希望将其全部放入Transactions 以防万一。关于Truncate的优点是它很快,因为从表中清除的每条记录都不需要额外的日志记录。
答案 3 :(得分:1)
如果事情可能同时发生(特别是如果在其他过程发生时可插入交错的任务),那么现有的解决方案都不安全。
您需要将数据插入临时表,然后插入临时表中的数据,然后根据临时表中的记录从登台表中删除数据。这可确保您只删除插入的记录,而不是插入时添加的其他记录。当然,你应该把所有这些都放在交易中,如@Ardman所示。
此外,如果不指定要插入的字段,则不应进行插入。假设有人重新创建了表并重新排列了字段,那么插入将插入错误的字段(如果数据类型兼容)或失败。
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的拼写错误。或者它会惹恼你的开发者多年!我还会考虑在dashboardTasks表中添加一个代理键,因为像你这样的多字段PK可能会导致性能问题,如果存在子表,则较小的int键不会。但仍然在自然键上做出一个独特的索引。
答案 4 :(得分:0)
您可以运行清除表格的DELETE
语句
DELETE FROM myTable
我的建议是使用BEGIN TRY
和BEGIN CATCH
,如果发生任何事情,您还没有从登台表中删除数据。
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
答案 5 :(得分:0)
您可以在一个存储过程中运行多个查询,因此,除非我遗漏了某些内容,否则您应该只能添加
DELETE staggingtasks WHERE <any criteria you need>
INSERT查询后...