2012-09-21 17 views
19

SQL Serverのこのコードで何が問題になっていますか?列作成後のSQL Serverの更新時に列名が無効

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     UPDATE REP_DSGN_SEC_GRP_LNK 
     SET OPT_LOCK = 0 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 

私はこれを実行すると、私が手:

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

更新コマンドです。

ありがとうございました。

答えて

33

この場合、列をNOT NULLとして追加し、1つのステートメントに既存の行の値を設定することで回避できます。as per my answer here

もっと一般的には、問題は解析/コンパイルの問題です。 SQL Serverは、ステートメントのいずれかを実行する前に、バッチ内のすべてのステートメントをコンパイルしようとします。

ステートメントがすべてのステートメントに存在しないテーブルを参照する場合、遅延コンパイルの対象となります。テーブルがすでに存在する場合は、既存のカラムを参照しないとエラーがスローされます。 DMLとは異なるバッチでDDLを実行するのが最善の方法です。

ステートメントが、既存のテーブル内に存在しない既存の列と存在しないテーブルを参照する場合、コンパイルが延期される前にエラーがスローされる場合とスローされない場合があります。

あなたは(例えばクライアントツールでバッチ区切りGOを使用して)別のバッチでそれを提出するか、またはEXECEXEC sp_executesqlを使用して別々にコンパイルされた子スコープでそれを行うことができます。

最初のアプローチでは、IF ...がバッチをスパンできないため、コードをリファクタリングする必要があります。あなたの情報については

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0'); 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 
+1

EXECが近づいてきました。ありがとう! – feradz

+0

これは私が何年も使ってきたアプローチであり、新しいカラムを追加してデータを入力したいときはいつでも、この厄介な動的SQLルートをとらなければならないと私は常に驚いています... –

0

、あなたはCOL_LENGTH機能をIF NOT EXISTSを置き換えることができます。 :それは列が見つかった場合は、

を探している

  1. テーブル名と

  2. 列が、それは、カラム例のデータ型の範囲を返し、2つのパラメータを取りますInt(4バイト)、見つからない場合はNULLを返します。

    これを次のように使用して、3つのステートメントを1つに結合することもできます。

    IF (SELECT COL_LENGTH('REP_DSGN_SEC_GRP_LNK','OPT_LOCK')) IS NULL 
    
    BEGIN 
    
        ALTER TABLE REP_DSGN_SEC_GRP_LNK 
        ADD OPT_LOCK NUMERIC(10, 0) NOT NULL DEFAULT 0 
    
    END; 
    

    もっと簡単になります。