20

次のSQLが与えられます:

IF EXISTS (SELECT * FROM sys.columns WHERE name = 'NewFieldName' AND object_id = OBJECT_ID('dbo.MyTableName'))
    RETURN

-- Add NewFieldName column to part of the Summer 2012 release cycle.
ALTER TABLE dbo.[MyTableName] ADD
    [NewFieldName] SmallINT NOT NULL
        CONSTRAINT DF_MyTableName_NewFieldName DEFAULT (2)

UPDATE [MyTableName] SET NewFieldName = 1 WHERE [Name] = 'FindMe' --Update one specific value

次のエラーメッセージが表示されます。

メッセージ207、レベル16、状態1、行10無効な列名'NewFieldName'。

基本的なものが欠けていることは確かですが、変更後に「GO」を付けようとすると、毎回UPDATEが実行されるため、実行したくありません。

このステートメントを構造化して、列が存在するかどうかを確認し、列が追加されていない場合は、UPDATEステートメントに記載されている値を設定するにはどうすればよいですか?

4

1 に答える 1

27

新しい列が追加された後にコンパイルされる新しい列を参照するステートメントが必要です。これを行う1つの方法は、を使用して子バッチとして実行することEXECです。

IF NOT EXISTS (SELECT * 
               FROM   sys.columns 
               WHERE  name = 'NewFieldName' 
                      AND object_id = OBJECT_ID('dbo.MyTableName')) 
BEGIN
  -- Add NewFieldName column to part of the Summer 2012 release cycle. 
  ALTER TABLE dbo.[MyTableName] 
           ADD [NewFieldName] SMALLINT NOT NULL 
           CONSTRAINT DF_MyTableName_NewFieldName DEFAULT (2) 

  EXEC(' UPDATE [MyTableName] SET NewFieldName = 1 WHERE [Name] = ''FindMe''') 
END

それが元々機能した理由は、おそらく、バッチがコンパイルされたときにテーブル自体が存在しなかったためです。つまり、テーブルを参照するテーブル内のすべてのステートメントは、遅延コンパイルの対象になります。

于 2012-04-22T14:44:27.213 に答える