我有一個進程根據發佈的元數據層中的更改動態更改我的SQL2K5表結構。查詢時出現死鎖INFORMATION_SCHEMA
例如,如果一個新的列需要添加和表沒有依賴關係 - 步驟是: 1.使用T-SQL對於任何索引&已經在表中存在主鍵[這些創建腳本腳本包括下面] 2.刪除該表 3.重新創建從具有新列的元層的表 4.執行在步驟#1中 5.創建的腳本使用BulkCopy
填充表以上是通過.NET程序集啓動的,每天在3個併發流中運行。
我在步驟1中收到死鎖錯誤 - 當我訪問INFORMATION_SCHEMA表格來編制索引/鍵時。我在這些腳本中使用了提示WITH(NOLOCK),認爲這應該可以防止3個這樣的操作併發運行時發生任何鎖定。一個表只能在1個流中處理(創建或腳本)。
還有什麼我需要做的嗎?
任何意見非常感謝。
[腳本]
ALTER Procedure [dbo].[s$spScriptPrimaryKeyForTable]
@Tablename varchar(100)
AS
-- Get all existing primary keys
DECLARE cPK CURSOR FOR
SELECT TABLE_NAME, CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WITH(NOLOCK)
WHERE upper(TABLE_NAME)=upper(@Tablename)
ORDER BY TABLE_NAME
DECLARE @PkTable SYSNAME
DECLARE @PkName SYSNAME
-- Loop through all the primary keys
OPEN cPK
FETCH NEXT FROM cPK INTO @PkTable, @PkName
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE @PKSQL NVARCHAR(4000) SET @PKSQL = ''
SET @PKSQL = 'ALTER TABLE ' + @PkTable + ' ADD CONSTRAINT ' + @PkName + ' PRIMARY KEY CLUSTERED ('
-- Get all columns for the current primary key
DECLARE cPKColumn CURSOR FOR
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WITH(NOLOCK)
WHERE TABLE_NAME = @PkTable AND CONSTRAINT_NAME = @PkName
ORDER BY ORDINAL_POSITION
OPEN cPKColumn
DECLARE @PkColumn SYSNAME
DECLARE @PkFirstColumn BIT SET @PkFirstColumn = 1
-- Loop through all columns and append the sql statement
FETCH NEXT FROM cPKColumn INTO @PkColumn
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@PkFirstColumn = 1)
SET @PkFirstColumn = 0
ELSE
SET @PKSQL = @PKSQL + ', '
SET @PKSQL = @PKSQL + @PkColumn
FETCH NEXT FROM cPKColumn INTO @PkColumn
END
CLOSE cPKColumn
DEALLOCATE cPKColumn
SET @PKSQL = @PKSQL + ')'
-- Print the primary key statement
-- PRINT @PKSQL
FETCH NEXT FROM cPK INTO @PkTable, @PkName
END
CLOSE cPK
DEALLOCATE cPK
SELECT ISNULL(@PKSQL,' ')
================
ALTER Procedure [dbo].[s$spScriptIndexesForTable]
@Tablename varchar(100)
AS
DECLARE @RetVal varchar(4000)
SET @RetVal = ''
-- Get all existing indexes, but NOT the primary keys
DECLARE cIX CURSOR FOR
SELECT OBJECT_NAME(SI.Object_ID), SI.Object_ID, SI.Name, SI.Index_ID
FROM Sys.Indexes SI WITH(NOLOCK)
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC WITH(NOLOCK) ON SI.Name = TC.CONSTRAINT_NAME AND OBJECT_NAME(SI.Object_ID) = TC.TABLE_NAME
WHERE TC.CONSTRAINT_NAME IS NULL
AND OBJECTPROPERTY(SI.Object_ID, 'IsUserTable') = 1
AND upper(OBJECT_NAME(SI.Object_ID))=upper(@Tablename)
ORDER BY OBJECT_NAME(SI.Object_ID), SI.Index_ID
DECLARE @IxTable SYSNAME
DECLARE @IxTableID INT
DECLARE @IxName SYSNAME
DECLARE @IxID INT
-- Loop through all indexes
OPEN cIX
FETCH NEXT FROM cIX INTO @IxTable, @IxTableID, @IxName, @IxID
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE @IXSQL NVARCHAR(4000)
--SET @PKSQL = ''
SET @IXSQL = 'CREATE '
-- Check if the index is unique
IF (INDEXPROPERTY(@IxTableID, @IxName, 'IsUnique') = 1)
SET @IXSQL = @IXSQL + 'UNIQUE '
-- Check if the index is clustered
IF (INDEXPROPERTY(@IxTableID, @IxName, 'IsClustered') = 1)
SET @IXSQL = @IXSQL + 'CLUSTERED '
SET @IXSQL = @IXSQL + 'INDEX ' + @IxName + ' ON [' + @IxTable + '] ('
-- Get all columns of the index
DECLARE cIxColumn CURSOR FOR
SELECT SC.Name,IC.[is_included_column],IC.is_descending_key
FROM Sys.Index_Columns IC WITH(NOLOCK)
JOIN Sys.Columns SC WITH(NOLOCK) ON IC.Object_ID = SC.Object_ID AND IC.Column_ID = SC.Column_ID
WHERE IC.Object_ID = @IxTableID AND Index_ID = @IxID
ORDER BY IC.Index_Column_ID,IC.is_included_column
DECLARE @IxColumn SYSNAME
DECLARE @IxIncl bit
DECLARE @Desc bit
DECLARE @IxIsIncl bit set @IxIsIncl = 0
DECLARE @IxFirstColumn BIT SET @IxFirstColumn = 1
-- Loop throug all columns of the index and append them to the CREATE statement
OPEN cIxColumn
FETCH NEXT FROM cIxColumn INTO @IxColumn, @IxIncl, @Desc
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@IxFirstColumn = 1)
BEGIN
SET @IxFirstColumn = 0
END
ELSE
BEGIN
--check to see if it's an included column
IF ((@IxIsIncl = 0) AND (@IxIncl = 1))
BEGIN
SET @IxIsIncl = 1
SET @IXSQL = @IXSQL + ') INCLUDE ('
END
ELSE
BEGIN
SET @IXSQL = @IXSQL + ', '
END
END
SET @IXSQL = @IXSQL + '[' + @IxColumn + ']'
--check to see if it's DESC
IF @Desc = 1
SET @IXSQL = @IXSQL + ' DESC'
FETCH NEXT FROM cIxColumn INTO @IxColumn, @IxIncl, @Desc
END
CLOSE cIxColumn
DEALLOCATE cIxColumn
SET @IXSQL = @IXSQL + ')'
-- Print out the CREATE statement for the index
--SELECT 'IXSQL: ' + @IXSQL
IF @RetVal IS NULL
SET @RetVal = ''
--SELECT 'Retval: ' + @RetVal
SET @RetVal = @RetVal + @IXSQL + ' '
FETCH NEXT FROM cIX INTO @IxTable, @IxTableID, @IxName, @IxID
END
CLOSE cIX
DEALLOCATE cIX
SELECT ISNULL(@RetVal,' ')
哪個過程導致死鎖,腳本主鍵或編寫腳本索引的過程?你爲什麼使用INFORMATION_SCHEMA,INDEXPROPERTY等代替sys.key_constraints,sys.index_columns,sys.indexes.is_clustered等? –