Sql-Server-2008-R2

即使在創建儲存過程時表存在,有沒有辦法強制延遲名稱解析?

  • September 11, 2020

在 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 

引用自:https://dba.stackexchange.com/questions/13522