【发布时间】:2011-04-03 05:56:22
【问题描述】:
我不是第一个遇到这些问题的人,我会在下面列出一些参考帖子,但我仍在寻找合适的解决方案。
我需要从 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:字符串文字太长
经过一些研究,我得出结论,用我的第二种方法解决问题根本不可行。
根据上述帖子,我有以下两个选择。
- Switch to ODP.NET(因为它应该是微软已弃用的数据库客户端中的一个错误)
- Insert the CLOB into a table 并从那里读取存储的过程
(The first post 说有些客户端有问题,但我的 (9i) 不在上述 10g/11g 版本范围内。)
您能确认这是仅剩的两个选项吗?或者有其他方法可以帮助我吗?
澄清一下:XML 不会最终保存在任何表中,而是由存储过程处理,该存储过程根据 XML 内容在某个表中插入一些记录。
我对这两个选项的考虑:
- 切换到 ODP.NET 很困难,因为我必须将它安装在到目前为止我没有系统访问权限的 Web 服务器上,而且因为我们可能还想在客户端上部署这段代码,所以每个客户端必须在部署过程中安装 ODP.NET。
- 绕过表使客户端代码变得相当复杂,并且在数据库适应/扩展 PL/SQL 例程方面也花费了相当多的精力。
【问题讨论】:
-
@Benny:ans LOB 存在问题,因此引用了 BLOB 帖子,但我在 CLOB 方面遇到了困难。我在我的帖子中找不到任何错字...
-
MyXML := '{0}';string.Format()正在用 xml 替换'{0}'- 但是,'...'是一个字符串文字,它属于VARCHAR2数据类型(不是CLOB)。 PL/SQL has a 32k limit onVARCHAR2s 这就是失败的原因。
标签: c# oracle stored-procedures clob system.data.oracleclient