【问题标题】:Oracle data access error: ORA-00936: missing expressionOracle 数据访问错误:ORA-00936:缺少表达式
【发布时间】:2022-05-05 16:55:42
【问题描述】:

我在我的 asp.net 应用程序中访问一个 Oracle 数据库,并收到此错误:

ORA-00936: 缺少表达式

我的c#代码是:

getInfoByPoNum = 
"SELECT h.SYS_HEADER_ID, 
    h.FOLIO1 AS INV_NUMBER, 
    v.VENDOR_NAME,
    CASE WHEN h.Comments LIKE '%CLOSED%' THEN 'CLOSED' ELSE NVL(h.Comments, 'OPEN') END AS CComments,
    h.ORG_ID
FROM    INV_HEADERS h, VENDORS v
WHERE   h.LOOKUP_CODE in ('STANDARD', 'BLANKET')
AND     h.VENDOR_ID = v.VENDOR_ID
AND     h.FOLIO1 = @invNumber"

OracleCommand CMD = new OracleCommand();
OracleConnection CONN = new OracleConnection(constring.ConnectionString);

CMD.Connection = CONN;
CONN.Open();

CMD.Parameters.Clear();
CMD.Parameters.Add(new OracleParameter("@invNumber", INVNumber));
CMD.CommandText = getInfoByPoNum;

using (var reader = CMD.ExecuteReader())
{
    while (reader.Read())
    {  

错误发生在 CMD.ExecuteReader()。
根据 SO 和 web 上的其他帖子,查询是正确的,并且在 oracle sql-developer 中运行。
是什么导致语法错误?

更新:如果我修改 oracle 查询并输入有效的发票编号值而不是 @invNumber,则查询在我的应用程序中执行得很好。

getInfoByPoNum = 
    "SELECT h.SYS_HEADER_ID, 
        h.FOLIO1 AS INV_NUMBER, 
        v.VENDOR_NAME,
        CASE WHEN h.Comments LIKE '%CLOSED%' THEN 'CLOSED' ELSE NVL(h.Comments, 'OPEN') END AS CComments,
        h.ORG_ID
    FROM    INV_HEADERS h, VENDORS v
    WHERE   h.LOOKUP_CODE in ('STANDARD', 'BLANKET')
    AND     h.VENDOR_ID = v.VENDOR_ID
    AND     h.FOLIO1 = 2241QSA"

【问题讨论】:

  • 你能给我们可以编译的C#代码吗?
  • 您是否尝试过更改将参数传递给查询的语法?代替@invNumber,将其发送为:invNumber
  • 你应该将你的命令、连接和阅读器包装到一个 using 块中,因为它们实现了IDisposable。有关示例,请参见 this question

标签: c# asp.net ora-00936


【解决方案1】:

我相信对于 Oracle,您的参数应该在查询中指定为 :invNumber,而不是 @invNumber

AND     h.FOLIO1 = :invNumber"

在设置参数时,它应该是这样的(只需删除@):

CMD.Parameters.Add(new OracleParameter("invNumber", INVNumber));

编辑

您可能还需要按名称启用参数绑定(我认为默认情况下它是位置):

CMD.BindByName = true;

【讨论】:

  • 当我删除 @ 时,我收到一个错误“ORA-00904: "INVNUMBER": invalid identifier”。我还包括了 BindByName,但没有运气
  • @user990423:听起来您没有在查询中输入冒号:。您确实需要它,但在实例化 OracleParameter 对象时不需要。仔细看我贴的代码。
  • 添加冒号并删除 @ 有效。谢谢@sstan
  • 我的查询中缺少冒号。非常感谢!!
  • 冒号是 Oracle 特有的,正如这些人所了解的,它是必需的。此外,使用 BindByName 无需担心参数顺序,因为参数在 SQL 中的位置不需要匹配相关参数集合的顺序。我从不依赖职位。
【解决方案2】:

尝试将所有查询放在同一行,似乎只执行字符串的第一行。还要检查是否没有任何转义字符或特殊字符必须用“\”字符处理。

【讨论】:

  • 当我将鼠标悬停在“CMD.CommandText”上时,我可以看到完整的查询;
  • 是的,但似乎只要有新行,它就会向您添加返回字符。尝试这样做(Y)
【解决方案3】:

根据我的经验,在 .NET/C# 的 Oracle 托管驱动程序中尝试使用终止分号执行 SQL 时,也可能发生这种情况。

因此,在这种情况下,请在包装器中执行 SQL 以确保一致性和 不要使用

SELECT * FROM X;

使用

SELECT * FROM X

换句话说,把它剥掉。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多