I have a stored procedure which truncates a not so large table (2M records but it will get bigger in the future) and then refills it. The sample version is like below:
ALTER PROCEDURE [SC].[A_SP]
AS
BEGIN
BEGIN TRANSACTION;
BEGIN TRY
TRUNCATE TABLE SC.A_TABLE
IF OBJECT_ID('tempdb..#Trans') IS NOT NULL DROP TABLE #Trans
SELECT
*
INTO
#Trans
FROM
(
SELECT
...
FROM
B_TABLE trans (NOLOCK)
INNER JOIN
... (NOLOCK) ON ...
LEFT OUTER JOIN
... (NOLOCK) ON ...
...
) AS x
INSERT INTO
SC.A_TABLE
(
...
)
SELECT
...
FROM
#Trans (NOLOCK)
DROP TABLE #Trans
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
THROW
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
END
This procedure takes a few hours to work. Sometimes I want to take a COUNT
to see how much is finished by using:
SELECT COUNT(*) FROM A_TABLE (NOLOCK)
This doesn't return anything (even with NOLOCK
) because there is LCK_M_SCH_S
lock on the table because of TRUNCATE
statement. I even can't do:
SELECT object_id('SC.A_TABLE')
The other interesting thing is; I sometimes stop the execution of the procedure through SSMS and even after that I can't take a COUNT
or select it's object_id
. The execution seems suspended
in sys.sysprocesses
and I have to close the query window to make it release the lock. I suspect it's because I use transactions and leave it in mid state by stopping the execution but I'm not sure.
I know that truncating the table doesn't take so much time since the table doesn't have any foreign keys or indexes.
What can be the problem? I may use DELETE
instead of this but I know that TRUNCATE
will be much faster here.
EDIT: DELETE
instead of TRUNCATE
works without any problem btw but I only want to use it as a last resort.