实体框架& Oracle:无法插入VARCHAR2> 1,999个字符

时间:2013-04-01 19:20:15

标签: 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:不一致的数据类型:预期 - 得到NCLOB

但是,在使用SQL Developer执行此操作时,我可以在字段中插入4,000个字符的字符串值。

有一个known ODAC bugsource #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论坛帖子中的那个,建议使用存储过程作为解决方法。谷歌告诉我,只有在使用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 - 无法处理VARCHAR2s超过2,000个字符。我没有完全跟随。无论是使用SQL Plus,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有关而错误......

1 个答案:

答案 0 :(得分:5)

最新的ODP.NET文档 - 从2012年9月开始的“11.2版本5生产(11.2.0.3.0)” - 在“实体框架相关提示,限制和已知问题”部分中说明了以下已知问题,其中包含问题代码块中“if”语句的错误:

  

如果在LINQ /的WHERE子句中绑定了2,000个或更多字符的字符串,或者长度为4,000个字节或更长的字节数组,则会遇到“ORA-00932:notistent datatypes”错误ESQL查询。如果在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:不一致的数据类型:expected - got NCLOB”错误。 [错误12630958]