2013-03-07 53 views
2

對於Sql Server 2005和2008我想檢查列是否已經存在於一個給定的表,並創建它,如果它不。這個新列應該有一個ExistingColumn的默認值。目前我需要使用動態sql來填充新列,因爲sql server會抱怨語法錯誤。將列添加到現有的表和默認值到另一列沒有動態sql

這是當前的SQL Server代碼:

IF NOT EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable')) 
BEGIN 
    ALTER TABLE [dbo].[ExistingTable] ADD [NewColumn] VARCHAR(50) NULL; 

    exec sp_executesql N'UPDATE [dbo].[ExistingTable] SET NewColumn = ExistingColumn' 

    ALTER TABLE [dbo].[ExistingTable] ALTER COLUMN [NewColumn] VARCHAR(50) NOT NULL 
END 
GO 

有沒有其他的辦法來解決這個問題,而不是訴諸動態sql?

+1

爲什麼不喜歡動態sql作爲解決方案? – 2013-03-07 19:03:04

+0

除了沒有獲得Management Studio的語法高亮和自動完成之外,我對它沒有任何問題。對於封面上真正發生的事情更加好奇。 – 2013-03-07 19:04:21

+0

啊,我通常用Print來代替exec,然後在另一個窗口粘貼它不是很亮,但是最好是試圖找出附近的錯誤,意思是 – 2013-03-07 20:44:11

回答

2

由於無論您是在創建列,您都可以執行兩個單獨的批次。

IF NOT EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable')) 
    BEGIN 
     ALTER TABLE [dbo].[ExistingTable] ADD [NewColumn] VARCHAR(50) NULL; 
    END 
    GO 
    IF EXISTS (SELECT TOP 1 1 FROM sys.columns WHERE [name] = N'NewColumn' AND OBJECT_ID = OBJECT_ID(N'ExistingTable')) 
    BEGIN 
     IF EXISTS (SELECT 1 FROM [dbo].[ExistingTable] WHERE NewColumn IS NULL) 
     BEGIN 
      UPDATE [dbo].[ExistingTable] SET NewColumn = ExistingColumn 
      ALTER TABLE [dbo].[ExistingTable] ALTER COLUMN [NewColumn] VARCHAR(50) NOT NULL 
     END 
    END 
    GO 
+0

值得注意的是,如果你運行第二個無需運行第一批或第一批錯誤就自行批量生產;上述所做的是讓你擺脫動態SQL。所以如果你正在尋找可重複性,那麼你就會陷入困境。 – 2013-03-08 20:47:00

2

SQL Server正在解析您的語句之前您的ALTER運行,並說「嘿,沒有這樣的列」。解析器不理解IF和其他分支,並且在混合DDL和DML時不能遵循事件序列 - 或者預測事件發生的順序以及運行時將發生的分支。

延遲名稱解析允許您訪問對象不存在,但不是不上做對象還不存在。

因此,動態SQL似乎是你必須這樣做的方式。