我在 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 相关......