C# 如何在sqlserver中使用游标删除大量表时清除死锁?

C# 如何在sqlserver中使用游标删除大量表时清除死锁?,c#,sql-server,asp.net-mvc,C#,Sql Server,Asp.net Mvc,我正在使用光标删除一组表。桌子的数量大约是400张。当计数达到105时,执行将挂起。请查找以下脚本: DECLARE @TblName NVARCHAR(MAX); DECLARE TBL_Cur CURSOR FOR (select name from sysobjects where name like 'xxx'); OPEN TBL_Cur; FETCH NEXT FROM TBL_Cur INTO @TblName WHILE (@@FETCH_S

我正在使用光标删除一组表。桌子的数量大约是400张。当计数达到105时,执行将挂起。请查找以下脚本:

DECLARE @TblName NVARCHAR(MAX);
DECLARE TBL_Cur CURSOR
FOR (select name from sysobjects 
      where name like 'xxx');
OPEN TBL_Cur;
FETCH NEXT FROM TBL_Cur INTO @TblName
            WHILE (@@FETCH_STATUS <> -1)
        BEGIN
            IF LEN(@TblName) >0
            BEGIN
                DECLARE @strsql nvarchar(max)
            if ('Create_ts' IN (select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where table_name = @TblName))
            BEGIN
                    SET @strsql = 'Select count(*) from' + @TblName + ' where DATEDIFF(HOUR,create_ts,getdate())>1'
                    Begin try
                    BEGIN TRAN
                    EXEC sp_executesql @strsql

                    COMMIT TRAN
                    End Try

                    Begin Catch

                    End catch
             END
             END
FETCH NEXT FROM TBL_Cur INTO @TblName
END
CLOSE TBL_Cur
DEALLOCATE TBL_Cur

提前感谢您的帮助。

我认为,如果您不执行字符串操作,而是一次性执行这些操作,则可以加快查询速度,这样您就可以在游标上花费更少的时间

我假定您希望所有表名都带有xxx+,它们应该有一列“create\u ts”。稍微修改了一下查询。我的解决办法是

DECLARE @tbl Table(tableName nvarchar(MAX) null, stmt nvarchar(MAX) null)

INSERT INTO @tbl(tablename, stmt)
SELECT T.TABLE_NAME, 'SELECT count(*) FROM [' + T.TABLE_NAME + '] WHERE
DATEDIFF(HOUR,create_ts,getdate())>1' 
FROM INFORMATION_SCHEMA.TABLES T 
INNER JOIN INFORMATION_SCHEMA.COLUMNS C ON T.TABLE_NAME = C.TABLE_NAME AND
T.TABLE_SCHEMA= C.TABLE_SCHEMA
WHERE T.TABLE_NAME  like 'xxx' AND C.COLUMN_NAME = 'Create_ts'

-- Open cursor and execute each row of @tbl
-- also instead of executing each row in separate transaction, 
-- put the loop  inside transaction and commit only once.

DECLARE @tableToBeChecked nvarchar(MAX)

IF NOT exists(SELECT object_name(P.object_id) as LockedTable FROM
 sys.dm_tran_locks AS L INNER JOIN sys.partitions AS P ON
 L.resource_associated_entity_id = p.hobt_id WHERE object_name(P.object_id)
 = @tableToBeChecked) 
BEGIN
-- table is not locked and can be deleted safely. 
-- still no guarantee that by the time you arrive here the table 
-- would still be unlocked.
END

呃,什么?……我不仅不知道你的意思,你的标题提到了一个我看不到的更新,你的问题正文提到了一个我也看不到的删除…@Mitch wheatI不清楚你在问什么?你可以使DATEDIFFHOUR,创建,getdate>1。@wewesthemenace。我已经在使用这个“DATEDIFFHOUR,create_ts,getdate>1”了,对吗?你的脚本真的很棒。但同样的问题也出现了。我想它会锁定列表中的某个表。你知道如何跳过锁定的表吗