裏面我有設計成是「安全」在不同的情況下運行,或者在同一實例多次,而不會造成任何不良數據或錯誤「無效列名」拋出可達腳本塊
大型SQL腳本編寫這樣的腳本時,我總是依賴於這樣的語法:
if not exists (select 1 from SYS.FOREIGN_KEYS where NAME = 'FK_BAR')
begin
alter table [MyTable]
add constraint FK_BAR foreign key (some_id) references Other_Table(some_id)
end
go
這通常工作得很好。但是,最近我遇到了一個場景,我無法防止在執行過程中拋出錯誤。在下面的代碼中,列「deprecated_column」已經從表foo下降:
if exists (select 1 from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'Foo' and COLUMN_NAME = 'deprecated_column')
and exists (select 1 from [Foo] where new_column is null)
begin
declare @updated int set @updated = 1;
while @updated > 0
begin
update top (500000)
Foo
set new_column = deprecated_column
where new_column is null
;
set @updated = @@rowcount;
end
end
go
如果我運行if
獨立於本計劃內兩個exist
的,他們返回‘無結果’的預期,這意味着內部代碼永遠不會被執行。但是,當我運行該腳本時,服務器將引發錯誤:Invalid column name 'deprecated_column'.
,並且該腳本被標記爲完成並顯示錯誤,這會導致在我們的系統上引發警報(即,DBA被通知並且必須檢查),其中正在導致一些不必要的開銷,應該是一個簡單的自動化任務。
是否有一些我忽略了的語法會讓這段代碼在所有情況下都不會出錯?
@SeanLange這是不正確你剛纔說的話,放在IF塊內的任何有效的SQL,如果控制從來沒有進入塊也不會有例外。 –
@ M.Ali你是對的......刪除我的評論。 :( –
這裏肯定有一個挑戰,如果被引用的表不存在,代碼將會正確編譯,但如果表存在,那麼它也會檢查被引用的列是否存在。延遲名稱解析 –