2016-05-30 26 views
0

私は、私の知られているON DUPLICATE KEY UPDATEをSQL Serverで動作する新しいアプリケーションに実装しようとしています。これはMySQLでのみ可能なので、次のコードを記述しましたが、パラメータを追加するときにエラーが発生します。C#で動的SQLにパラメータを追加

これらはエラーメッセージです:

ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @FaeBezeichnung-Skalarvariable muss deklariert werden. 

ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @VeraendertAm-Skalarvariable muss deklariert werden. 

ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @mitIDref-Skalarvariable muss deklariert werden. 

マイコードは次のようになります。

ます。strSQL:

DECLARE @faeID AS int 
begin tran 
    SELECT @faeID = faeID FROM mdb_Faehigkeiten WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable) 
    SET VeraendertAm = @VeraendertAm 
    WHERE mitIDref = @mitIDref AND faeIDref = @faeID 
    if @@rowcount = 0 
    begin 
     INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm) 
     VALUES (@mitIDref, @faeID, @VeraendertAm) 
    end 
commit tran 

C番号:

OdbcConnection conn = GetConnection(); 
OdbcCommand cmd = new OdbcCommand(strSQL, conn); 
cmd.Parameters.Add("@mitIDref", OdbcType.Int).Value = dgv[0, item.iRow].Value; 
cmd.Parameters.Add("@VeraendertAm", OdbcType.DateTime).Value = dgv[item.iColumn, item.iRow].Value; 
cmd.Parameters.Add("@FaeBezeichnung ", OdbcType.VarChar).Value = dgv.Columns[item.iColumn].HeaderText; 

try 
{ 
    conn.Open(); 
    cmd.ExecuteNonQuery(); 
} 
catch { throw; } 
finally { conn.Close(); } 

は、誰もがこれで私を助けることができる、または動的SQL文にパラメータを実装するために基本的に可能ではないでしょうか?

+2

はkurzBez = @ FaeBezeichnung' – Steve

+0

私はパラメータを追加mdb_Faehigkeitenからあなたのクエリsyntax_ 'SELECT @faeID = faeIDを修正:)、パラメータのリストを取得するために私がsp_batch_paramsは、このようにストアドプロシージャを拡張使用します彼らはとにかく置き換えられないのですか?さて、上記のコメントは最初のエラーを修正しました=)...しかし、宣言はまだ "不足しています" – Diego

+0

私は構文が間違っていました...間違ったテーブル。しかし、***はい***、私は 'すべての変数を宣言しなければならなかった、彼らはどこに置き換えられません。 – Diego

答えて

0

はこのように見て、あなたのSQLスクリプトを調整し、私はデータを使用しているタイプと値に使用されるデータ型を変更します。

DECLARE @FaeBezeichnung int = 1 
DECLARE @VeraendertAm int = 2 
DECLARE @mitIDref int = 3 
DECLARE @faeID AS int 
begin tran 
    SELECT @faeID = faeID 
    FROM mdb_Faehigkeiten 
    WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable) 
    SET VeraendertAm = @VeraendertAm 
    WHERE 
     mitIDref = @mitIDref AND 
     faeIDref = @faeID 
    if @@rowcount = 0 
    begin 
     INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm) 
     VALUES (@mitIDref, @faeID, @VeraendertAm) 
    end 
commit tran 
1

MSDNによると:

。 ODBC用の.NET Frameworkデータプロバイダは、 という名前のパラメータをSQLステートメントまたはOdbcCommandによって というストアドプロシージャに渡すことはサポートしていません。いずれの場合も、疑問符(?) プレースホルダを使用します。代わりに

DECLARE @faeID AS int 
begin tran 
    SELECT @faeID = faeID FROM mdb_Faehigkeiten WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable) 
    SET VeraendertAm = @VeraendertAm 
    WHERE mitIDref = @mitIDref AND faeIDref = @faeID 
    if @@rowcount = 0 
    begin 
     INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm) 
     VALUES (@mitIDref, @faeID, @VeraendertAm) 
    end 
commit tran 

ボトムラインは、あなたが

DECLARE @FaeBezeichnung int = ? 
DECLARE @VeraendertAm int = ? 
DECLARE @mitIDref int = ? 
DECLARE @faeID AS int 
begin tran 
    SELECT @faeID = faeID 
    FROM mdb_Faehigkeiten 
    WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable) 
    SET VeraendertAm = @VeraendertAm 
    WHERE 
     mitIDref = @mitIDref AND 
     faeIDref = @faeID 
    if @@rowcount = 0 
    begin 
     INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm) 
     VALUES (@mitIDref, @faeID, @VeraendertAm) 
    end 
commit tran 

を使用する必要がありますし、また、あなたはcmd.Parametersコレクション/リスト内のパラメータの位置に注意する必要があります。

なぜですか? @VarNameはSQL Serverに固有のものですが、ODBCはデータベースの言語拡張とは独立しています。

補足:TXとエラー/例外には注意が必要です。たとえば、BEGIN TRANの前にSET XACT_ABORT ONを使用し、C#でSqlExceptionを傍受します。また、(serializable)テーブルヒントを使用する代わりに、私はSET TRANSACTION ISOLATION LEVEL SERIALIZABLEの前にBEGIN TRAN... READ COMMITTEDを、COMMITの後には、catchセクションの中でSqlExceptionのセクションに使用します。このトピックには別の質問が必要です。

別の注記: SQL2005および2008/[R2](?

enter image description here

+0

それは私を激しく襲った。なぜあなたは '(シリアル化可能な)'に対して 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE'を取るのですか?私はそれが "違いは関係ありません"というコメントを読んだので、これを選んだ。 – Diego

+0

'SET TRANSACTION ... SERIALIZABLE'は、' SET ... S'と 'SET ... RC'の間に、そして2つの範囲の間に(' 'テーブルがたくさんある場合)' 'すべてのテーブルに対して' 'SERIALIZABLE'分離レベルを強制します:' 'kurzBez =また、 'mitIDRef = _とfaeIDRef = _'にも適用されます。 'WITH(S)' 'mdb_F'の' S'分離レベルのみを強制します。また、 '(mitIDRef、faeIDRef)'にユニークなインデックスを作成します( 'UPDATE'文で使用されるフィルタを参照)。 –

関連する問題