【问题标题】:ORA-01425: escape character must be character string of length 1ORA-01425: 转义字符必须是长度为 1 的字符串
【发布时间】:2018-07-02 04:27:45
【问题描述】:

我们正在开发与 .net (MVC) 和 Oracle 数据库一起使用的软件。之后,我们不得不在新服务器上安装新版本的 Oracle (12.1.0),我们在搜索时遇到了这个错误,而在 12.2.0 版本中我们没有这样的错误。 错误:

ORA-01425: 转义字符必须是长度为 1 的字符串

我的查询在这里

availableTasks.Where(task => task.Document.RegistrationNumber.Contains(searchkeyWord) || task.WorkflowNumber.Contains(searchkeyWord) || task.Description.Contains(searchkeyWord));

值得一提的是,当我删除 task.Document.RegistrationNumber.Contains(searchkeyWord)task.WorkflowNumber.Contains(searchkeyWord) || task.Description.Contains(searchkeyWord) 时,它可以完美运行。

我的 Linq 查询输出:

SELECT 
"GroupBy1"."A1" AS "C1"
FROM ( SELECT 
    COUNT(1) AS "A1"
    FROM   (SELECT "Extent1"."Id" AS "Id1", "Extent1"."Document_Id" AS "Document_Id", "Extent1"."Member_Id" AS "Member_Id", "Extent1"."Command_Id" AS "Command_Id", "Extent1"."InitialTask_Id" AS "InitialTask_Id", "Extent1"."Sender_Id" AS "Sender_Id", "Extent1"."Receiver_Id" AS "Receiver_Id", "Extent1"."Department_Id" AS "Department_Id", "Extent1"."PreviousTask_Id" AS "PreviousTask_Id", "Extent1"."OpeningTime" AS "OpeningTime", "Extent1"."ClosingTime" AS "ClosingTime", "Extent1"."IsDone" AS "IsDone", "Extent1"."Description" AS "Description", "Extent1"."MetaData" AS "MetaData", "Extent1"."WorkflowNumber" AS "WorkflowNumber", "Extent1"."Comment" AS "Comment", "Extent2"."Id" AS "Id2", "Extent2"."PortCommunity_Id" AS "PortCommunity_Id", "Extent2"."Accessibility_Id" AS "Accessibility_Id", "Extent2"."IssuedUser_Id" AS "IssuedUser_Id", "Extent2"."ChangingTime" AS "ChangingTime", "Extent2"."RegistrationNumber" AS "RegistrationNumber", "Extent2"."RegistrationDate" AS "RegistrationDate", "Extent2"."SequenceNumber" AS "SequenceNumber", "Extent2"."DocumentStatus" AS "DocumentStatus", "Extent2"."DocumentType" AS "DocumentType"
        FROM  "KISH"."Task" "Extent1"
        INNER JOIN "KISH"."Document" "Extent2" ON "Extent1"."Document_Id" = "Extent2"."Id"
        WHERE ("Extent1"."IsDone" <> 1) ) "Filter1"
    LEFT OUTER JOIN "KISH"."User" "Extent3" ON "Filter1"."Receiver_Id" = "Extent3"."Id"
    WHERE (((("Filter1"."Member_Id" = :p__linq__0) AND ("Filter1"."Command_Id" = :p__linq__1)) OR ("Filter1"."Command_Id" <> :p__linq__2)) AND ("Filter1"."PortCommunity_Id" = :p__linq__3) AND ((:p__linq__4 <> 1) OR ("Filter1"."Receiver_Id" IS NULL) OR ("Filter1"."Receiver_Id" = :p__linq__5)) AND ( EXISTS (SELECT 
        1 AS "C1"
        FROM "KISH"."Permission" "Extent4"
        WHERE (("Extent4"."User_Id" = :p__linq__6) AND ("Extent4"."Member_Id" = :p__linq__7) AND ("Extent4"."PortCommunity_Id" = :p__linq__8) AND ( EXISTS (SELECT 
            1 AS "C1"
            FROM "KISH"."RoleCommand" "Extent5"
            WHERE (("Extent4"."Role_Id" = "Extent5"."Role_Id") AND ("Extent5"."Command_Id" = "Filter1"."Command_Id"))
        )) AND (("Extent4"."Department_Id" IS NULL) OR ("Filter1"."Department_Id" IS NULL) OR ("Extent4"."Department_Id" = "Filter1"."Department_Id") OR (("Extent4"."Department_Id" IS NULL) AND ("Filter1"."Department_Id" IS NULL))))
    )) AND (("Filter1"."RegistrationNumber" LIKE :p__linq__9 ESCAPE '\') OR ("Filter1"."WorkflowNumber" LIKE :p__linq__10 ESCAPE '\') OR ("Filter1"."Description" LIKE :p__linq__11 ESCAPE '\')))
)  "GroupBy1"SQL: 
SQL: -- p__linq__0: 'db717061-06f1-4235-8413-1d76f65ba80f' (Type = Binary, IsNullable = false)
SQL: -- p__linq__1: '19ccc777-634f-43c6-a5d3-037ae78be91c' (Type = Binary, IsNullable = false)
SQL: -- p__linq__2: '19ccc777-634f-43c6-a5d3-037ae78be91c' (Type = Binary, IsNullable = false)
SQL: -- p__linq__3: '04922971-1ea5-4f76-8de6-13b6e460364b' (Type = Binary, IsNullable = false)
SQL: -- p__linq__4: 'True' (Type = Decimal, IsNullable = false)
SQL: -- p__linq__5: '1d0c0570-9dd0-4aa4-92d7-8055b567c351' (Type = Binary, IsNullable = false)
SQL: -- p__linq__6: '1d0c0570-9dd0-4aa4-92d7-8055b567c351' (Type = Binary, IsNullable = false)
SQL: -- p__linq__7: 'db717061-06f1-4235-8413-1d76f65ba80f' (Type = Binary, IsNullable = false)
SQL: -- p__linq__8: '04922971-1ea5-4f76-8de6-13b6e460364b' (Type = Binary, IsNullable = false)
SQL: -- p__linq__9: '%30%' (Type = Object)
SQL: -- p__linq__10: '%30%' (Type = Object)
SQL: -- p__linq__11: '%30%' (Type = Object)

我完全被这个问题弄糊涂了。我不知道它适用于不同的 Oracle 版本或其他东西。

【问题讨论】:

  • 我假设您正在使用带有 Oracle 提供程序的 EF,您能否提供由 LINQ 语句生成的 Oracle SQL 查询(当然它包含消息所指的ESCAPE 语句)?
  • 是的,我正在使用 EF
  • @Tetsuya Yamamoto - 我放了 sql 代码
  • 尝试使用Trim()availableTasks.Where(task =&gt; task.Document.RegistrationNumber.Contains(searchkeyWord.Trim()) || task.WorkflowNumber.Contains(searchkeyWord.Trim()) || task.Description.Contains(searchkeyWord.Trim()));。这应该会生成LTRIMRTRIM,从而避免使用问题所在的ESCAPE '\'
  • @Tetsuya Yamamoto - 谢谢你,它有效

标签: .net asp.net-mvc oracle


【解决方案1】:

使用实体框架ODP在LINQ中实现Contains()方法在某些情况下直接处理System.String参数时似乎无法正常工作,它会在PL/SQL查询中生成LIKEESCAPE '\'语句,这将抛出ORA-01425 错误(如similar issue here 所示)。为了减轻这种行为,只需在 Contains() 方法中使用 Trim() 来对抗字符串参数:

availableTasks.Where(task => task.Document.RegistrationNumber.Contains(searchkeyWord.Trim()) 
                     || task.WorkflowNumber.Contains(searchkeyWord.Trim()) 
                     || task.Description.Contains(searchkeyWord.Trim()));

Trim() 方法将生成INSTRTRIM 语句(或LTRIM-RTRIM 对)作为LIKEESCAPE 语句的替换,如下例所示:

SELECT <snip> FROM <snip> WHERE [condition] AND ((NVL(INSTR("Filter1"."RegistrationNumber", TRIM(:p__linq__9)), 0)) > 0) 
OR ((NVL(INSTR("Filter1"."WorkflowNumber", TRIM(:p__linq__10)), 0)) > 0)
OR ((NVL(INSTR("Filter1"."Description", TRIM(:p__linq__11)), 0)) > 0)

通过实现INSTRTRIM,查询将在处理包含System.String 值的LINQ 生成参数(:p__linq__XX)时平稳运行。

【讨论】:

  • Trim() 方法也适用于我,因为在 Any() 中使用 Contains() 会抛出 ora-01425
【解决方案2】:

您发布的 SQL 语句中的 ESCAPE 很好 - ESCAPE '\'

但这是 LINQ

记录的查询文本

查看发送到 DB 的真实查询语句的最佳方法是激活 10046 跟踪

 ALTER SESSION SET tracefile_identifier = escape;
 alter session set events '10046 trace name context forever, level 12';

在您的连接中运行该语句。

您会在 DB Server 的跟踪文件夹中找到一个文件,例如 xxx_ora_NNNN_ESCAPE.trc。

我怀疑你会看到使用类似

的语句
escape '\\'

【讨论】:

  • 我对 Oracle (12.1.0) 没有任何问题。当我更改为 12.2.0 时出现此问题。我认为它需要在 oracle 中进行一些设置。
【解决方案3】:

我们遇到了同样的问题

通过将参数CURSOR_SHARING更改为EXACT解决

【讨论】:

    【解决方案4】:

    select emp.emp_id from employee emp where emp.NAME like '%\\_%' ESCAPE '\\';

    【讨论】:

      猜你喜欢
      • 2013-05-25
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 2021-10-12
      • 2021-09-19
      • 2018-07-22
      • 2021-07-09
      • 1970-01-01
      相关资源
      最近更新 更多