我不是第一个遇到这些问题的人,我会在下面列出一些参考帖子,但我仍在寻找合适的解决方案。
我需要从 C# Web 服务调用存储过程(Oracle 10g 数据库)。Web 服务器安装了 Oracle 9i 客户端,我正在使用 Microsofts 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:字符串文字太长
经过一些研究,我得出结论,用我的第二种方法解决问题根本不可行。
在上述帖子之后,我有以下两个选择。
- 切换到 ODP.NET(因为它应该是 Microsoft 已弃用的 DB 客户端中的错误)
- 将 CLOB 插入表中并从那里读取存储的过程
(第一篇文章说有些客户端有问题,但我的(9i)不在上述的 10g/11g 版本范围内。)
你能确认这是仅剩的两个选项吗?或者有其他方法可以帮助我吗?
澄清一下:XML最终不会保存在任何表中,而是由存储过程处理,该存储过程根据 XML 内容在某个表中插入一些记录。
我对这两个选项的考虑:
- 切换到 ODP.NET 很困难,因为我必须将它安装在到目前为止我没有系统访问权限的 Web 服务器上,而且因为我们可能还想在客户端上部署这段代码,所以每个客户端都必须在部署过程中安装 ODP.NET。
- 绕行表使客户端代码更加复杂,并且在数据库适应/扩展 PL/SQL 例程上也需要付出相当多的努力。