次の.Netコードを実行すると:
using (var c = Shared.DataSources.BSS1.CreateCommand())
{
c.CommandText = "\r\nSelect c1, c2, c3, rowid \r\nFrom someSpecificTable \r\nWhere c3 = :p0";
var p = c.CreateParameter() as Oracle.DataAccess.Client.OracleParameter;
c.Parameters.Add(p);
p.OracleDbType = Oracle.DataAccess.Client.OracleDbType.Varchar2;
p.DbType = System.Data.DbType.AnsiString;
p.Size = 20;
p.Value = "007";
p.ParameterName = ":p0";
using (var r = c.ExecuteReader())
{
r.Read();
}
}
次のエラーが発生します。
ORA-01460: unimplemented or unreasonable conversion requested
ORA-02063: preceding line from XXX
これは私のデータベースではなく、データベースリンクから取得したselectステートメントを制御できません。そのテーブルIS)。
面白いことに、ExecuteReaderの直前に次のコードを追加すると、正常に実行されます。
c.CommandText = c.CommandText.Replace("\r\n", " ");
残念ながら、SQL noreを制御できないため、これは良い解決策ではありません。そのように変更することはできます。
テーブル自体の場合、列は次のとおりです。c1Number(5)c2 varchar2(40)c3 varchar2(20)。
後に続くORA-02063がデータベースリンクに関する何かを示していることは知っていますが、シノニムテーブルを調べたところ、どのdatabase_linkからも取得されておらず、\ r\nがデータベースリンクに影響を与えるとは思われません。
バインドされたパラメーターなしでクエリを実行しようとしましたが、機能しましたが、一般的な用語で実行するのは悪い習慣です。
問題は、.Netベースではない競合ツールが機能しているため、一般的な問題ではないことです。
また、自分の環境では問題を再現できませんでした。これは顧客のデータベースとサイトです。インスタントクライアント11.1.6.20を使用しており、インスタントクライアント11.2.3.0でもテストしました。
Dbは10で、dbリンクはOraclev8データベースへのリンクです
どんな助けもいただければ幸いです
ついに答えが見つかりました!!!
調査してコードを反映した後、パラメーターの方向を入出力に変更することで、問題が解決されたことがわかりました。
p.Direction = ParameterDirection.InputOutput;
この問題は、簡単な手順で再現できます。つまり、where句に4000文字を超える文字列リテラルが含まれるSQLクエリでは、「ORA-01704:文字列リテラルが長すぎます」というエラーが発生します。
ただし、JDBCを介して同じクエリを実行すると、「ORA-01460:実装されていないまたは不当な変換が要求されました」というメッセージが表示されます。
多くの調査の結果、ODP.NETから使用されるバインドされたパラメーターと、DBLINKからV8Oracleサーバーへのターゲットテーブルがあることがすべてであることがわかりました。
バインドされたパラメータを削除すると、すべて機能しました。
少し前のことですが、バインドされたパラメーターに送信される文字列の文字列の長さを変えることと関係があると思います。 sizeプロパティを無視しているようです。したがって、最初のクエリで長さ10の文字列を送信し、2番目の文字列で長さ12の文字列を送信すると、そのエラーが発生します。
オラクルの記事も見つかりました: https://community.Oracle.com/thread/2460796?tstart=
およびそのパッチ: https://support.Oracle.com/CSP/main/article?cmd=show&type=NOT&id=745005.1
しかし、実際にそれを解決する修正をコードで見つけました。次の答えを参照してください。
これが誰かに役立つことを願っています。
受け入れられた答えは私にはうまくいきませんでした。ただし、添付のリンクを読んだ後、SQLの編集を伴うものの、以下を適用しました。
私の場合、バインド変数の左の最大値を知っていました(最初の呼び出し後に長さが短くなることが問題の原因です)。そこで、.NET文字列をパディングし、SQLにTRIM
を追加しました。あなたの例に従う:
c.CommandText = "\r\nSelect c1, c2, c3, rowid \r\nFrom someSpecificTable \r\nWhere c3 = TRIM(:p0)";
...
p.Value = "007".PadRight(10);