我試圖構建一個腳本,將所有外鍵放在特定模式中(我正在創建一個新的數據庫,它需要腳本到其他幾個位置,一個測試環境和一個生產)。擁有這三個獨立環境的最簡單方法是在「開發」中使用我的「CREATE」腳本,然後在以後通過其他環境進行處理。這需要(作爲一種可能的解決方案)「CREATE」腳本的開始是If Exists(...) DROP...
。ORDER BY更改字符串串聯SQL
我已經解決了我遇到的問題,但希望能有人解釋我看到的行爲(見下文)。
此代碼工作(我得到了所有記錄作爲自己的SQL語句的陳述):
DECLARE @SQL VARCHAR(MAX) = ''
DECLARE @Schema VARCHAR(100) = 'SchemaName'
SELECT
@SQL = @SQL
+ 'ALTER TABLE ' + tpa.name + CHAR(13) + CHAR(10)
+ CHAR(9) + 'DROP CONSTRAINT ' + fk.name +';' + CHAR(13) + CHAR(10)
FROM
sys.foreign_keys AS fk
JOIN sys.foreign_key_columns AS fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.tables AS tpa
ON fk.parent_object_id = tpa.object_id
JOIN sys.columns AS cpa
ON tpa.object_id = cpa.object_id AND
fkc.parent_column_id = cpa.column_id
JOIN sys.tables AS tref
ON fkc.parent_object_id = tref.object_id
JOIN sys.columns AS cref
ON tref.object_id = cref.object_id AND
fkc.referenced_column_id = cref.column_id
WHERE
SCHEMA_NAME(fk.schema_id) = @Schema
PRINT @SQL
此代碼不起作用(它只返回記錄集的最後一行):
DECLARE @SQL VARCHAR(MAX) = ''
DECLARE @Schema VARCHAR(100) = 'SchemaName'
SELECT
@SQL = @SQL
+ 'ALTER TABLE ' + tpa.name + CHAR(13) + CHAR(10)
+ CHAR(9) + 'DROP CONSTRAINT ' + fk.name +';' + CHAR(13) + CHAR(10)
FROM
sys.foreign_keys AS fk
JOIN sys.foreign_key_columns AS fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.tables AS tpa
ON fk.parent_object_id = tpa.object_id
JOIN sys.columns AS cpa
ON tpa.object_id = cpa.object_id AND
fkc.parent_column_id = cpa.column_id
JOIN sys.tables AS tref
ON fkc.parent_object_id = tref.object_id
JOIN sys.columns AS cref
ON tref.object_id = cref.object_id AND
fkc.referenced_column_id = cref.column_id
WHERE
SCHEMA_NAME(fk.schema_id) = @Schema
ORDER BY
OBJECT_NAME(fk.parent_object_id)
,OBJECT_NAME(fk.referenced_object_id)
,fk.name
PRINT @SQL
出錯行似乎是在ORDER BY
的OBJECT_NAME(fk.referenced_object_id)
作爲評論說出來解決問題,但我不明白爲什麼它的失敗。我的懷疑是有些事情是由內在或某事組成的。
即使包括從ORDER BY
所有列似乎並沒有幫助:
DECLARE @SQL VARCHAR(MAX) = ''
DECLARE @Schema VARCHAR(100) = 'UserMgmt'
SELECT
@SQL = @SQL
+ 'ALTER TABLE ' + tpa.name + CHAR(13) + CHAR(10)
+ CHAR(9) + 'DROP CONSTRAINT ' + fk.name +';' + CHAR(13) + CHAR(10)
+ '--' + OBJECT_NAME(fk.referenced_object_id) + ', ' + OBJECT_NAME(fk.parent_object_id) + CHAR(13) + CHAR(10)
FROM
sys.foreign_keys AS fk
JOIN sys.foreign_key_columns AS fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.tables AS tpa
ON fk.parent_object_id = tpa.object_id
JOIN sys.columns AS cpa
ON tpa.object_id = cpa.object_id AND
fkc.parent_column_id = cpa.column_id
JOIN sys.tables AS tref
ON fkc.parent_object_id = tref.object_id
JOIN sys.columns AS cref
ON tref.object_id = cref.object_id AND
fkc.referenced_column_id = cref.column_id
WHERE
SCHEMA_NAME(fk.schema_id) = @Schema
ORDER BY
OBJECT_NAME(fk.parent_object_id)
,OBJECT_NAME(fk.referenced_object_id)
,fk.name
PRINT @SQL
但是,更改爲引用表的JOIN
語句也使這項工作:
DECLARE @SQL VARCHAR(MAX) = ''
DECLARE @Schema VARCHAR(100) = 'UserMgmt'
SELECT
@SQL = @SQL
+ 'ALTER TABLE ' + tpa.name + CHAR(13) + CHAR(10)
+ CHAR(9) + 'DROP CONSTRAINT ' + fk.name +';' + CHAR(13) + CHAR(10)
+ '--' + OBJECT_NAME(fk.referenced_object_id) + ', ' + OBJECT_NAME(fk.parent_object_id) + CHAR(13) + CHAR(10)
FROM
sys.foreign_keys AS fk
JOIN sys.foreign_key_columns AS fkc
ON fkc.constraint_object_id = fk.object_id
JOIN sys.tables AS tpa
ON fk.parent_object_id = tpa.object_id
JOIN sys.columns AS cpa
ON tpa.object_id = cpa.object_id AND
fkc.parent_column_id = cpa.column_id
JOIN sys.tables AS tref
ON fk.referenced_object_id = tref.object_id
JOIN sys.columns AS cref
ON tref.object_id = cref.object_id AND
fkc.referenced_column_id = cref.column_id
WHERE
SCHEMA_NAME(fk.schema_id) = @Schema
ORDER BY
OBJECT_NAME(fk.parent_object_id)
,OBJECT_NAME(fk.referenced_object_id)
,fk.name
PRINT @SQL
誰能解釋這種行爲?
的可能重複[爲什麼SQL Server會忽略在指定的ORDER BY子句時字符串連接vaules(http://stackoverflow.com/questions/5538187/why-sql-server-ignores-vaules-in-string -concatenation-when-order-by-clause-speci) –
這裏的順序仍然會導致它失敗,即使在select語句中指定了列時也是如此。但是,更改JOIN子句似乎允許ORDER BY工作。看我的編輯。 – Jon