I have an asp.net program, that adds tasks to my staging table and executes a stored procedure that takes these tasks and places them in my actual table, i would like to delete the records after they are added, because my staging table will get too big fast.
here is my stored procedure code
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
You could run a
DELETE
statement that cleans out the tableDELETE FROM myTable
My suggestion would be to use
BEGIN TRY
andBEGIN CATCH
so if anything happens you haven't deleted the data from the staging table.If things could be happening concurrently (in particular if the staggingtasks can be inserted into while the other process happens), then none of the existing solutions are safe.
You need to Insert the data to a temp table, then insert the data from the temp table and then delete the data from the staging table based on the records in the temp table. This ensures you only deleted the records you inserted and not some others added while the insert happens. And of course you should put all this in a transaction as @Ardman showed.
Further you should not ever do an insert without specifying the fields you are inserting into. Suppose someone recreated the table and rearranged the fields, then your insert would insert into the wrong fields (if the datatypes are compatible) or fail.
And if this hasn't gone to production yet, please fix the misspelling of StagingTasks. Or it will annoy your developers for years! I would also consider putting in a surrogate key to the dashboardTasks table as a multiple field PK like you have is likely to cause performance issues that a smaller int key would not especially if there are child tables. But still make a unique index on the natural key.
Have a delete statement with the same criteria you have for insert except that you now use EXISTS instead of NOT EXISTS.
Something like this:
Possibly you could do the
DELETE
from your staging table combined with theOUTPUT
clause. andINSERT
the result of theOUTPUT
clause into your main table to do this all in one atomic statement.There are some restrictions listed in BOL though which may make this approach unviable.
The output_table cannot:
Full syntax for your query...
You can run multiple queries in a single stored procedure, so unless I'm missing something you should just be able to add
after the INSERT query...
Remember that deleting will log everything so in time your log may grow too big. If you don't care about the data in your staging table, then try the TRUNCATE command instead after your insert:
Like others are saying, you may want to put it all into Transactions just in case. The plus about Truncate is that it is fast since no additional logging is required for each record you are purging from the table.