Sql-Server

如果表存在而不使用 sp_executesql,則更新表中的行

  • July 16, 2021

我有一種情況,我需要對大量類似的數據庫執行查詢。他們中的大多數人都會有一個表,我需要在其中更新一些行,但其中一些沒有表。

我想編寫一個查詢,該查詢具有IF檢查表是否存在而不需要EXEC sp_executesql用於該語句的UPDATE語句。有沒有辦法在 SQL Server 中做到這一點?

這是我今天正在做的一個例子:

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[MyTableName]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
 -- this is what I want to be able to do but cannot
 UPDATE [dbo].[MyTableName] SET [SomeColumn] = NULL WHERE [SomeColumn] NOT IN (1, 2, 3)

 -- this is the only way I know to do this without an error
 EXEC sp_executesql N'UPDATE [dbo].[MyTableName] SET [SomeColumn] = NULL WHERE [SomeColumn] NOT IN (1, 2, 3)'
END

我可能有更多的這個 if 語句檢查不同的表表存在並更新它們,但批處理中沒有其他邏輯。沒有它會給我一個關於表不存在的錯誤,因為它需要在評估語句sp_executesql之前編譯整個批處理。IF

我不是sp_executesql特別反對,而是一般來說是動態SQL。我想要一個不需要我將內部查詢編碼/轉義為字元串並允許我在編寫內部查詢時使用 IDE 提供語法突出顯示和自動完成的解決方案。

這裡的問題是 SQL Server 在解析 SQL 語句時會驗證對象,因此如果對像不存在,它就會失敗,但是,有一個技巧可以解決這個問題。

SQL Server 分析 IF 語句中的對象名稱,但不驗證 ELSE 部分中的對象。不是檢查對像是否存在,如果存在則採取行動,而是檢查對像是否不存在,如果存在則採取行動。

例子:

CREATE TABLE TestTable1 (RowData VARCHAR(255))
GO
INSERT INTO TestTable1 VALUES ('Test data')
GO

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TestTable2')
BEGIN
   PRINT 'Table does not exist'
END
ELSE
BEGIN
   UPDATE TestTable2
   SET RowData = 'Text update'
END

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TestTable1')
BEGIN
   PRINT 'Table does not exist'
END
ELSE
BEGIN
   UPDATE TestTable1
   SET RowData = 'Text update'
END

在範例中,TestTable2 不存在,但是,腳本仍然執行,因為在 IF 語句的 ELSE 部分中引用了失去的表。這允許對腳本進行解析,並且在執行時它永遠不會到達缺少對象的腳本部分,因此不會導致錯誤。

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