Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 实体框架及;Oracle:无法插入VARCHAR2>;1999个字符_String_Oracle_Entity Framework_Ora 00932_Varchar2 - Fatal编程技术网

String 实体框架及;Oracle:无法插入VARCHAR2>;1999个字符

String 实体框架及;Oracle:无法插入VARCHAR2>;1999个字符,string,oracle,entity-framework,ora-00932,varchar2,String,Oracle,Entity Framework,Ora 00932,Varchar2,我在Oracle表中创建了一个4000字符的VARCHAR2字段。我在Visual Studio 2010、.NET Framework 4和中使用LINQ to Entities将字符串值插入字段。当我尝试插入大于1999个字符的字符串值时,会出现以下内部异常: Oracle.DataAccess.Client.OracleException ORA-00932:不一致的数据类型:应为-已获取NCLOB 但是,在使用SQL Developer执行此操作时,我可以在字段中插入4000个字符串值,

我在Oracle表中创建了一个4000字符的VARCHAR2字段。我在Visual Studio 2010、.NET Framework 4和中使用LINQ to Entities将字符串值插入字段。当我尝试插入大于1999个字符的字符串值时,会出现以下内部异常:

Oracle.DataAccess.Client.OracleException

ORA-00932:不一致的数据类型:应为-已获取NCLOB

但是,在使用SQL Developer执行此操作时,我可以在字段中插入4000个字符串值,而不会出现任何问题

有一个()在保存到XMLTYPE字段时有2000个字符的限制,但我没有保存到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:

2:

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”参数的值,但如前所述,当它超过1999个字符时,会发生异常。(当跟踪这个SQL时,我传递了一个4000字符的字符串作为参数,当然出现了异常。)DBA还提到了某些SQL客户机(例如SQLPlus)无法处理超过2000个字符的VARCHAR2。我没有完全听懂。无论是使用SQLPlus、SQLDeveloper还是任何其他工具,Oracle仍将查询4000个字符的VARCHAR2字段。另外,我的魔法数字是1999个字符;不是2000个字符。DBA是否意味着一个参数中可以包含多少个字符有限制?更重要的是,当我在SQLDeveloper中执行此SQL并为参数输入4000个字符的字符串时,它可以完美地工作。因此,我仍然完全不明白为什么它不能通过LINQ工作到实体。我还在我的程序中尝试了以下代码,以在“msg”变量中使用4000个字符串运行类似的查询,这也非常有效:

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…

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

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

较旧的ODP.NET文档(2011年5月发布的“11.2.0.3.0版产品”)说明了相同的已知问题,因此显然这是一个已知问题已有一段时间了

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

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

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" ;
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();