即使在創建儲存過程時表存在,有沒有辦法強制延遲名稱解析?
在 SQL Server 中創建儲存過程時,您可以引用不存在的表。但是,如果該表確實存在,那麼您在過程中引用的任何列都必須存在於該表中(延遲名稱解析)。
是否可以指示 SQL Server 推遲過程中引用的所有表的名稱解析,而不管它們是否存在?我確實想保持一般語法檢查,所以即使有可能,將儲存過程定義破解到系統表中也不是一種選擇。
我希望我要求這樣做可能看起來有點奇怪*,*所以這裡有一些背景:我從用 C# 編寫的應用程序自動生成表定義和儲存過程,而且我很難更改程式碼以根據 SQL 需要對更改進行排序他們。我的程式碼“保證”架構在事務中是一致的,但目前我不能保證在定義引用它們的儲存過程之前定義表列。
下面是 C# 創建的 SQL 的規範範例,它“說明”了我要解決的問題。
--Say this table already exists. CREATE TABLE myTable ( a NVARCHAR(MAX) ) GO --My C# code creates something like this BEGIN TRAN GO --the stored procedure gets generated first. CREATE PROCEDURE mySproc AS BEGIN SELECT a,b FROM myTable END --then the table update ALTER TABLE myTable ADD b nvarchar(MAX) COMMIT TRAN
我可以在 C# 程式碼中解決這個問題,但我希望我可以在 SQL 中進行一個簡單的“魔術”調整。這將為我節省很多時間。
不。
只是打字我感到很內疚,但不,很遺憾。這是我第一次聽說這個案例,而且非常有意義。最好在https://feedback.azure.com/forums/908035-sql-server上送出請求,您的孫子將能夠做到。;-)
萬一您仍然感興趣,您可以使用一種潛在的解決方法。這是更新後的程式碼,它將
#deferResolution
臨時表引入過程中的每個查詢。因為臨時表只在執行時存在,所以即使正確的列在myTable
.
#deferResolution
由於查詢優化器可以證明這WHERE NOT EXISTS
總是評估為真的方式,您甚至會為過程中的每個語句獲得相同的執行計劃(不引用表)。話雖如此,這是一個可怕的黑客攻擊,主要是為了學術興趣,並且可能存在崩潰的邊緣情況。正如 Aaron 所提到的,以正確的順序進行所有模式更改可能會更好。
--Say this table already exists. CREATE TABLE myTable ( a NVARCHAR(MAX) ) GO --My C# code creates something like this BEGIN TRAN GO --the sproc gets generated first. CREATE PROCEDURE mySproc AS BEGIN CREATE TABLE #deferResolution (dummy INT NOT NULL) SELECT a,b FROM myTable WHERE NOT EXISTS (SELECT * FROM #deferResolution WHERE 0=1) END --then the table update ALTER TABLE myTable ADD b nvarchar(MAX) COMMIT TRAN