Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将记录添加到实际表后,从暂存表中删除记录_Sql_Sql Server 2005_Stored Procedures - Fatal编程技术网

Sql 将记录添加到实际表后,从暂存表中删除记录

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

我有一个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

您可以运行
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一样。