0

動的SQLを使用してストアドプロシージャを作成しています。

私の手順では、同様の列のテーブルを10個ほど言いました。

たとえば、DesignationDepartmenttablesを検討すると、Designationtableには次の列があります。

Designation, Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn 

Departmentテーブルには次の列があります。

Department, Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn

同様に、他に8つのテーブルがあります。

ストアドプロシージャでは、データを更新してすべてのテーブルに挿入する必要があります。そのため、テーブルごとにupdate&insertステートメントを作成する代わりに、テーブル名をパラメーターとして受け取り、そのテーブルに行が既に存在するかどうかを確認するストアドプロシージャを使用しています。

その行が存在する場合、そのレコードは更新されます。そうでない場合、そのレコードはそれぞれのテーブルに挿入されます。

    ALTER PROC UpdateMasterItems
    (
        @MasterTypeTmp  varchar(50),
        @NameTmp    varchar(50),
        @CodeTmp    varchar(10))
    AS
    BEGIN   
       DECLARE @CntTmp numeric(2,0)

       EXEC('select count(*)' + @CntTmp + ' from ' + @MasterTypeTmp + ' where ' + @MasterTypeTmp  + ' = ' + @NameTmp)

       IF(@CntTmp > 1)
       BEGIN
          EXEC('UPDATE ' + @MasterTypeTmp + ' SET ' + 'Code = ' + @CodeTmp + ', ModifiedBy = CURRENT_USER, MOdifiedOn = CURRENT_TIMESTAMP WHERE' + @MasterTypeTmp + ' = ' +  @NameTmp)
          RETURN 10
       END      
       ELSE
       BEGIN    
          EXEC('INSERT INTO ' + @MasterTypeTmp + '(' + @MasterTypeTmp + ', Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn )  VALUES (' + @NameTmp + ',' + @CodeTmp + ',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )') 
          RETURN 11
       END
END

@MasterTypeTmpテーブル名はどこにありますか( Department/ Designation.....にすることができます)

手順の実行中にエラーが発生します:

Execステートメント:

EXEC UpdateMasterItems 'Designation', 'TestName', 'TestCode'

エラーステートメント:

無効な列名'TestName'。

列名'TestCode'が無効です。

ただし、TestNameTestCodeは列名ではありません。これらは列の値です。動的クエリが間違っているか、問題がどこにあるかを教えてください。

前もって感謝します

ムーニカ

4

3 に答える 3

0

文字列の連結に一部が欠落して'おり、dbは値を列名として解釈します。

EXEC('INSERT INTO ' + @MasterTypeTmp + '(' + @MasterTypeTmp + ', Code, EntryBy, EntryOn, ModifiedBy, ModifiedOn )  
VALUES (''' + @NameTmp + ''',''' + @CodeTmp + ''',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )') 
于 2013-03-15T20:08:24.697 に答える
0

エラーメッセージは、列名をでラップしたためだと思います'(つまり、'Designation'間違っています)。する必要がありますDesignation

しかし、他の問題もあります。

  1. 動的SQLの外部で変数を定義し、内部で割り当てることはできないと思います。したがってdynamic sql runs in a different session、スコープ外で定義された変数は不明です。(すなわち; @CntTmp

  2. チェックし@CntTmp > 1ているのに、実際にはcount(*)値を割り当てていません(理由1のためにとにかく機能しません)

  3. @CntTmpレコード数が99を超えるとオーバーフローします(悪いデータがない場合は実際には問題になりません)

説明した方法でこの作業を行う必要がある場合は、変数を宣言し、レコードの存在を確認してから、を更新/挿入する必要がありますall within the same dynamic query。を使用して変数なしで行うことができますif exists (select ....) update ... else insert...

于 2013-03-15T20:09:15.250 に答える
0

まず、この部分でエラーが発生します。Error converting data type varchar to numeric.

DECLARE @CntTmp numeric(2,0)
EXEC('select count(*)' + @CntTmp + ' from ' + @MasterTypeTmp + ' where ' + @MasterTypeTmp  + ' = ' + @NameTmp)

CntTmpは数値であり、その式で直接使用できないためです。

これに変更した場合:

EXEC('select count(*)' + cast(@CntTmp as varchar(30)) + ' from ' + @MasterTypeTmp + ' where ' + @MasterTypeTmp  + ' = ' + @NameTmp)

動的SQLでは変数を直接使用できないため、エラーが発生します。CntTmpまた、はnullであるため、出力は提供されません。

numericしたがって、 toをキャストした結果を格納する別の変数を作成し、ISNULLvarchar関数を実行して、変数がnullの場合に値を与えることができます。

'次に、列の値が欠落しています。

そして、これが有効なストアドプロシージャです。

ALTER PROC UPDATEMASTERITEMS   
( @MASTERTYPETMP VARCHAR(50), @NAMETMP VARCHAR(50), @CODETMP VARCHAR(10))    
AS

BEGIN

DECLARE @CNTTMP NUMERIC(2,0)
DECLARE @CNTTMPVAL VARCHAR(30) = ISNULL(CAST(@CNTTMP AS VARCHAR(30)) , '')

EXEC ('SELECT COUNT(*) ' + @CNTTMPVAL + ' FROM ' + @MASTERTYPETMP + ' WHERE ' + @MASTERTYPETMP  + ' = ''' + @NAMETMP + '''')
IF(@CNTTMP > 1)
    BEGIN
     EXEC('UPDATE ' + @MASTERTYPETMP + ' SET ' + 'CODE = ''' + @CODETMP + ''', MODIFIEDBY = CURRENT_USER, MODIFIEDON = CURRENT_TIMESTAMP WHERE' + @MASTERTYPETMP + ' = ''' +  @NAMETMP + '')
     RETURN 10
    END
ELSE
    BEGIN 
    EXEC('INSERT INTO ' + @MASTERTYPETMP + '(' + @MASTERTYPETMP + ', CODE, ENTRYBY, ENTRYON, MODIFIEDBY, MODIFIEDON )  VALUES (''' + @NAMETMP + ''',''' + @CODETMP + ''',' + 'CURRENT_USER, CURRENT_TIMESTAMP, CURRENT_USER, CURRENT_TIMESTAMP )') 
     RETURN 11
    END

END

とにかく、これを使用してSQLをフォーマットできます

于 2013-03-15T20:13:15.467 に答える