string - Entity Framework 和 Oracle : Cannot Insert VARCHAR2 > 1, 999 个字符

标签 string oracle entity-framework ora-00932 varchar2

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

Oracle.DataAccess.Client.OracleException

ORA-00932: inconsistent datatypes: expected - got NCLOB


但是,使用 SQL Developer 时,我可以在字段中插入一个 4,000 个字符的字符串值,而不会出现任何问题。
有一个known ODAC bug ( source #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”的身份收到对我的帖子的回复。如果我收到有用的回复,我一定会分享这方面的知识。)
编辑:如果有帮助,下面是我的代码中失败的两个 block 。我在对第一个 block 进行故障排除时创建了第二个 block ,只是为了看看是否有任何区别。在检查字符串值是否已插入(“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 客户端 - 例如 SQLPlus - 无法处理超过 2,000 个字符的 VARCHAR2。我没有完全遵循。无论是使用 SQLPlus、SQL Developer 还是任何其他工具,Oracle 仍将查询一个 4,000 个字符的 VARCHAR2 字段。另外,我的魔数(Magic Number)是 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 相关......

最佳答案

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

An "ORA-00932 : inconsistent datatypes" error can be encountered if a string of 2,000 or more characters, or a byte array with 4,000 bytes or more in length, is bound in a WHERE clause of a LINQ/ESQL query. The same error can be encountered if an entity property that maps to a BLOB, CLOB, NCLOB, LONG, LONG RAW, XMLTYPE column is used in a WHERE clause of a LINQ/ESQL query.



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

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

An "ORA-00932: inconsistent datatypes: expected - got NCLOB" error will be encountered when trying to bind a string that is equal to or greater than 2,000 characters in length to an XMLType column or parameter. [Bug 12630958]

关于string - Entity Framework 和 Oracle : Cannot Insert VARCHAR2 > 1, 999 个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15750172/

相关文章:

c# - 当传递 keySelector 时,Linq to Entities OrderBy 会更早地评估查询

entity-framework - 如果访问导航属性没有预先加载(并且延迟加载被禁用),则配置 EF 抛出

asp.net-mvc - 使用 EntityFramework 和映射的 ViewModels 的 ASP.NET MVC 最佳实践

c# - 最小化 LINQ 字符串 token 计数器

oracle - 有人使用 PL/SQL Web Toolkit 吗?

perl - 如何从 Perl 访问 Oracle 数据库?

SQL - 没有规范就无法编译 <package> 的主体

凯撒密码

visual-studio - 是否有正则表达式可以在一个句子中找到两个不同的词?

java - 字符串数组在android中只返回一个字符串