2

私はado.netでOracleデータベースを使用しようとしていますが、それは苦痛な経験を証明しています。Oracle Client(Oracle.Data名前空間)を使用しています。

次のクエリは、クエリウィンドウから正常に実行されます。

UPDATE PRINT_ARGUMENT SET VALUE = 'Started' WHERE REQUEST_ID = 1 AND KEYWORD = '{7D066C95-D4D8-441b-AC26-0F4C292A2BE3}'

ただし、OracleCommandを作成すると、ORA-01722でも同じことが起こります。理由がわかりません。

var cmd = cnx.CreateCommand();
cmd.CommandText = @"
UPDATE PRINT_ARGUMENT
SET VALUE = :value 
WHERE REQUEST_ID = :requestID AND KEYWORD = :key";

cmd.Parameters.Add(new OracleParameter("requestID", (long)1); cmd.Parameters.Add(new OracleParameter("key", "{7D066C95-D4D8-441b-AC26-0F4C292A2BE3}"); cmd.Parameters.Add(new OracleParameter("value", "Started");

cnx.Open(); try { int affected = cnx.ExecuteNonQuery(); } finally { cnx.Close(); }

デバッガーでコマンドを調べると、パラメーターが正しいタイプにマップされているように見えます。requestIDにはOracleDbType.Int64があり、キーと値は両方ともOracleDbType.Varchar2です。パラメータのも正しいです。

同じアプローチを使用してまったく同じ列(requestID、keyword、value)を操作する他のクエリがあることを考えると、これはさらに奇妙になります-そしてそれらは問題なく機能します。

レコードの場合、列タイプはrequestID NUMBER(10,0);です。キーVARCHAR2(30); 値VARCHAR2(2000)。

Oracleによると、ORA-01722の「無効な数値」は、文字列を数値に変換できなかったことを意味します。私の文字列値はどちらも数値ではなく、それらのために作成されたOracleParametersも数値でもありません。

4

2 に答える 2

4

デフォルトでは、ODP.NETは、SQLに実際の名前がある場合でも(?だけでなく)、名前ではなく位置でパラメーターをバインドします。したがって、実際にはrequestID:valueに、key:requestIDに、value:keyにバインドしています。

cmd.Parameters.Addコード内の順序を修正するか、 BindByNameを使用してODP.NETにパラメーター名を使用するように指示します。

于 2011-11-14T12:18:02.917 に答える
3

名前付きパラメータを使用しているため、Oracleクライアントにそのことを通知する必要があります。そうしないと、パラメータが混同されます(キーは:valueに割り当てられます):

OracleParameter parameter = new OracleParameter("requestID", (long)1);
parameter.BindByName = true;
cmd.Parameters.Add(parameter);

それは奇妙で予想外の振る舞いですが、それはそうです。

于 2011-11-14T11:53:25.720 に答える