4

我在 Oracle 表中创建了一个 4,000 个字符的 VARCHAR2 字段。我正在使用 LINQ to Entities with Visual Studio 2010、.NET Framework 4 和ODAC 11.2 Release 4 和 Oracle Developer Tools for Visual Studio (11.2.0.3.0)将字符串值插入到字段中。当我尝试插入大于 1,999 个字符的字符串值时,我得到以下内部异常:

Oracle.DataAccess.Client.OracleException

ORA-00932: 不一致的数据类型: 预期 - 得到 NCLOB

但是,使用 SQL Developer 时,我可以在字段中插入一个 4,000 个字符的字符串值,而不会出现任何问题。

有一个已知的 ODAC 错误源 #2),其中保存到 XMLTYPE 字段时有 2,000 个字符的限制,但我没有保存到 XMLTYPE 字段。我的 GAC 中有 Oracle.DataAccess 2.112.3.0,我考虑更新到上述 Oracle 软件的第 5 版 (11.2.0.3.20),但“Oracle Developer Tools for Visual Studio”似乎是唯一的组件从第 4 版更新,我相信“Oracle Data Provider for .NET 4”是需要更新的组件。在我的 .NET 项目中,System.Data.Entity 和 System.Data.OracleClient 都是运行时版本 4.0.30319。

无论如何,我只是想知道是否有其他人遇到过这个错误,如果是这样,是否找到了任何解决方案——除了上面链接的 Oracle 论坛线程中建议使用存储过程作为解决方法的解决方案。Google 告诉我,人们仅在使用 XMLTYPE 字段时才会遇到此错误,但我不能是唯一在使用 VARCHAR2 字段时遇到此错误的人,可以吗?

(FWIW,我也希望在上面链接的 Oracle 论坛帖子中以用户“997340”的身份收到对我的帖子的回复。如果我收到有用的回复,我一定会分享这方面的知识。)

编辑:如果有帮助,下面是我的代码中失败的两个块。我在对第一个块进行故障排除时创建了第二个块,只是为了看看是否有任何区别。在检查字符串值是否已插入(“if”语句)以及实际插入字符串值(“AddObject”语句)时,我得到了异常。

1:

if (!(from q in db.MSG_LOG_MESSAGE where q.MESSAGE == msg select q.MESSAGE).Any())
{
  db.MSG_LOG_MESSAGE.AddObject(new MSG_LOG_MESSAGE { MESSAGE = msg });
  db.SaveChanges();
}

2:

if (!db.MSG_LOG_MESSAGE.Any(q => q.MESSAGE == msg))
{
  db.MSG_LOG_MESSAGE.AddObject(new MSG_LOG_MESSAGE { MESSAGE = msg });
  db.SaveChanges();
}

4月3日更新:

我能够跟踪从上面第一个代码块中的“if”语句发送到 Oracle 的 SQL。这里是:

SELECT
CASE WHEN ( EXISTS (SELECT
        1 AS "C1"
        FROM "SEC"."MSG_LOG_MESSAGE" "Extent1"
        WHERE ("Extent1"."MESSAGE" = :p__linq__0)
)) THEN 1 WHEN ( NOT EXISTS (SELECT
        1 AS "C1"
        FROM "SEC"."MSG_LOG_MESSAGE" "Extent2"
        WHERE ("Extent2"."MESSAGE" = :p__linq__0)
)) THEN 0 END AS "C1"
FROM  ( SELECT 1 FROM DUAL ) "SingleRowTable1" ;

不幸的是,与我合作的 DBA 没有为我提供“p_linq_0”参数的值,但如前所述,当它超过 1,999 个字符时,就会发生异常。(在跟踪这个 SQL 时,我传递了一个 4,000 个字符的字符串作为参数,当然发生了异常。)DBA 还提到了某些 SQL 客户端 - 例如 SQL Plus - 无法处理超过 2,000 个字符的 VARCHAR2 . 我没有完全遵循。是否使用 SQL此外,SQL Developer 或任何其他工具,Oracle 仍将查询 4,000 个字符的 VARCHAR2 字段。另外,我的幻数是 1,999 个字符;不是 2,000 个字符。DBA 是否可能意味着参数中可以包含多少个字符?更重要的是,当我在 SQL Developer 中执行此 SQL 并为参数输入一个 4,000 个字符的字符串时,它可以完美运行。所以我仍然对为什么它不能通过 LINQ to Entities 工作感到非常困惑。我还在我的程序中尝试了以下代码,以在“msg”变量中使用 4,000 个字符的字符串运行类似的查询,效果也很好:

using Oracle.DataAccess;
using Oracle.DataAccess.Client;
using System.Data;

...

OracleConnection conn = new OracleConnection("Data Source=[MASKED];User Id=[MASKED];Password=[MASKED]");
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT message FROM msg_log_message WHERE message = '" + msg + "'";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
string result1 = dr.GetString(0);
conn.Dispose();

现在,我仍然指责 ODAC 存在错误,因为它与 LINQ to Entities 相关......

4

1 回答 1

5

2012 年 9 月的“11.2 Release 5 Production (11.2.0.3.0)”的最新 ODP.NET 文档在“实体框架相关提示、限制和已知问题”部分下陈述了以下已知问题,该文件解决了来自问题代码块中的“if”语句:

如果在 LINQ/ESQL 查询的 WHERE 子句中绑定了 2,000 个或更多字符的字符串或长度为 4,000 个字节或更多的字节数组,则会遇到“ORA-00932:不一致的数据类型”错误。如果在 LINQ/ESQL 查询的 WHERE 子句中使用映射到 BLOB、CLOB、NCLOB、LONG、LONG RAW、XMLTYPE 列的实体属性,则会遇到相同的错误。

较早的 ODP.NET 文档 - 用于 2011 年 5 月的“发布 11.2.0.3.0 生产” - 陈述了相同的已知问题,因此显然这已经是一段时间的已知问题。

上述文档均未提及在问题代码块中的“AddObject”语句中遇到相同的错误,但该问题与提到的 XMLType 字段的另一个已知问题非常相似:

尝试将长度等于或大于 2,000 个字符的字符串绑定到 XMLType 列或参数时,将遇到“ORA-00932:不一致的数据类型:预期 - 得到 NCLOB”错误。[错误 12630958]

于 2013-06-26T15:25:50.473 回答