これらの問題を抱えたのは私が初めてではなく、以下にいくつかの参考記事をリストしますが、まだ適切な解決策を探しています.
C# Web サービスからストアド プロシージャ (Oracle 10g データベース) を呼び出す必要があります。Web サーバーには Oracle 9i クライアントがインストールされており、Microsoft を使用していますSystem.Data.OracleClient
。
このプロシージャは、XML を CLOB として受け取ります。XML が 4000 バイトを超えたとき(これは通常の使用例です)、次のエラーに遭遇しました。
ORA-01460 - 実装されていない、または不当な変換が要求されました
さらに、ストアド プロシージャを C# から直接呼び出すのではなく、匿名の PL/SQL コードを定義する有望な回避策を見つけました。このコードは OracleCommand として実行されます。XML は文字列リテラルとして埋め込まれ、プロシージャ コールはそのコード内から実行されます。
private const string LoadXml =
"DECLARE " +
" MyXML CLOB; " +
" iStatus INTEGER; " +
" sErrMessage VARCHAR2(2000); " +
"BEGIN " +
" MyXML := '{0}'; " +
" iStatus := LoadXML(MyXML, sErrMessage); " +
" DBMS_OUTPUT.ENABLE(buffer_size => NULL); " +
" DBMS_OUTPUT.PUT_LINE(iStatus || ',' || sErrMessage); " +
"END;";
OracleCommand oraCommand = new OracleCommand(
string.Format(LoadXml, xml), oraConnection);
oraCommand.ExecuteNonQuery();
残念ながら、このアプローチは、XML が 32 KB 程度を超えるとすぐに失敗するようになりました。今回のエラーは、次の PL/SQL コンパイラに起因します。
ORA-06550: 行1、列87: PLS-00172: 文字列リテラルが長すぎます
いくつかの調査の後、2番目のアプローチで問題を解決することは不可能であると結論付けました。
上記の投稿に続いて、次の2つのオプションがあります。
- ODP.NET に切り替えます(Microsoft の廃止された DB クライアントのバグであると想定されているため)
- CLOB をテーブルに挿入し、ストアド プロシージャをそこから読み取るようにします。
(最初の投稿では、一部のクライアントにはバグがあると記載されていましたが、私の (9i) は前述の 10g/11g バージョンの範囲には含まれていません。)
これらの 2 つのオプションしか残っていないことを確認できますか? または、私を助ける別の方法はありますか?
明確にするために: XMLは最終的にどのテーブルにも保存されませんが、XML の内容に基づいていくつかのテーブルにいくつかのレコードを挿入するストアド プロシージャによって処理されます。
2つのオプションに関する私の考慮事項:
- ODP.NET への切り替えは困難です。これまでのところ、システムにアクセスできない Web サーバーに ODP.NET をインストールする必要があり、クライアントにもコードをデプロイする必要があるためです。デプロイメントの一部として ODP.NET をインストールします。
- テーブルを迂回すると、クライアント コードがかなり複雑になり、PL/SQL ルーチンを適応/拡張するデータベースにかなりの労力がかかります。