【问题标题】:autogenerated sql code: single backslash as an escape character is failing自动生成的 sql 代码:作为转义字符的单反斜杠失败
【发布时间】:2011-04-07 06:57:56
【问题描述】:

我正在查询一个 oracle 9i 数据库:

SELECT * FROM table WHERE column LIKE '%' || 'someText' || '%' 转义 '\';

它失败并出现错误“转义字符必须是长度为 1 的字符串”(ORA-01425 错误),而在 oracle express 10g 数据库中成功。

将其设置为双反斜杠 (ESCAPE '\\') 可以解决 oracle 9i 数据库的问题,但会为 10g 数据库生成相同的 ORA-01425 错误。

我无法编辑 SQL,因为它是通过 Telerik OpenAccess ORM 自动生成的。

导致上述SQL的Linq代码是:

activity.Name.Contains.("someText")

我希望两个数据库都处理 ESCAPE '\'...

提前致谢!

【问题讨论】:

  • 我建议您添加一个标签 - 在您的帖子中添加“linq”,这样也许一些 Linq 专家会注意到它。也许添加来自您的 cmets 的信息,以便在前面有更多信息。我还没有足够的代表来为您编辑它,但这可能会帮助您获得更好的答案。
  • 感谢您的提示,我也编辑了标签和问题。

标签: linq oracle telerik escaping backslash


【解决方案1】:

不熟悉 Linq,但我对您在哪里执行查询感到有点困惑 - 您是否只是将生成的代码粘贴到针对两个数据库运行的 SQL*Plus 中,至少可以解释这种行为?

如果您在 SQL*Plus 中执行此操作,请在每个环境中执行 show escape;我怀疑 9i 会报告escape "\" (hex 5c),而 10g 会报告escape off。这可能表明之前在 9i 实例中设置了转义处理,但在(可能是更新的)10g 实例中没有。

如果到目前为止证明其中任何一个相关,请尝试在 10g 会话中执行 set escape \ 并再次尝试 \\ 版本。在 9i 中尝试使用 escape off 并尝试使用单 \ 版本。现在两者都应该工作了。

假设你还在我身边,下一个问题是为什么 9i 有这个设置;可能有一个 login.sql 或 glogin.sql 文件自动设置它。您可以将其删除,只要它不会影响其他任何内容,以允许生成的代码原样运行。

如果您打算以其他方式执行代码,我认为这些都不相关;不确定您是否只是在 SQL*Plus 中测试和调试生成的代码,并最终会在其他地方执行它(再次缺乏对 Linq 的了解),在这种情况下,无论如何这可能是一个暂时的问题。

我也不确定你到底在逃避什么......

【讨论】:

  • Alex,我得到了自动生成的代码,并自己在每个数据库中进行了测试。考虑到表也完全相同(它们是使用相同的脚本创建的),看到相同 SQL 命令的不同输出确实让我感到惊讶。我在两者上都尝试了“show escape”,并在两者上都“escape off”。感谢您建议检查此设置,很高兴了解导致这种不同行为的某些设置!但是,就我现在的情况而言,问题已经解决了:)
  • 我使用 Linq 来使用 ORM (Telerik OpenAccess)。 ORM 使用我的 C# 和 Linq,并生成 SQL 代码来处理数据库。转义是为搜索功能自动生成的。 (我不知道为什么,但可能是为了防止特殊字符或其他东西......这是一个 Web 应用程序项目。)
【解决方案2】:

试试:

  SELECT * FROM TABLENAME 
  WHERE COLUMNNAME LIKE '\%' ESCAPE '\';

通常 LIKE 中的 ESCAPE 符号用于允许搜索符号 '%' 和 '_'

【讨论】:

  • escape '\\\\' 适用于第一个数据库,escape '\\' 适用于第二个数据库。我也希望单个反斜杠在第一个反斜杠中起作用!原因是这是映射器自动生成的 sql,我无法编辑...
  • @naruu,是失败的确切查询吗?因为在我的数据库(9 和 10g)上一切正常。 SELECT * FROM all_tables WHERE table_name LIKE '%' ESCAPE '\';但不起作用将 '\\' 或 '\\\'
  • 单反斜杠在 9i 上失败,双反斜杠在 10g express 上失败。 ORM 使用单斜杠生成(自动)SQLcode,我希望它也可以在 9i 上工作(实际上,我希望相同的 sql 代码可以在任何最近的 oracle 数据库上工作)......不知道我应该是什么寻找。应用程序和映射工作正常,除了这个转义子句。将应用程序设置为与 oracle 9i 服务器数据库一起运行时,它仅因 ESCAPE 单反斜杠而失败。
  • 它应该像迈克尔描述的那样工作。几个问题.. 你能用不同的字符代替反斜杠吗?另外,你能确认一下进入数据库的实际代码吗?我猜你的调用应用程序中的反斜杠字符在被发送到数据库之前发生了一些事情。
  • 感谢克雷格的建议!但是我无法更改 SQL。它是由 Telerik Open Acess ORM 自动生成的,并且使用单个反斜杠精确地查询数据库。自动生成的 SQL 始终相同。我自己查询了每个数据库(使用 oracle 客户端 SQL Developer),并验证了我在这个问题中描述的内容 - 当查询包含转义反斜杠子句时,数据库对完全相同的查询的响应不同。
【解决方案3】:

您可以完全避免反斜杠问题。尝试在转义字符周围使用花括号。

http://download.oracle.com/docs/cd/B10500_01/text.920/a96518/cqspcl.htm

【讨论】:

  • 这不是特定于 oracle 文本和使用 contains 运算符的查询吗?
  • 感谢 sql_mommy 和 Jörn Horstmann 的意见!不幸的是,我无法修改 sql,因为它是自动生成的。以下 Linq 代码:[activity.Name.Contains.("someText")] 使用单个反斜杠(通过 Telerik OpenAccess ORM)转换为以下 SQL:[c."NAME" LIKE '%' || '一些文本' || '%' ESCAPE '\'] 所以是的,这个问题只发生在包含...生成的 SQL 代码有效且可在 express 10g 数据库中使用...
  • 有道理 - 实际上,我昨天查了这个,无论如何我都错了。花括号不适用于反斜杠。根据 oracle 文档(和我的测试),反斜杠应该用双反斜杠转义。您是否尝试过没有转义命令?所以“像'%\\'这样的列在哪里?我认为这两者都应该起作用,但我实际上有11g - 所以我无法确定它。当然,因为它是自动生成的,我不知道如何你可以改变它。
  • 感谢 sql_mommy 为我查找主题。我无法更改自动生成的代码,但是,我可以尝试查询以查看它们是如何工作的。用双反斜杠转义只会解决问题:它在 9i 上成功,它在 10g express 上给出 ORA-01425 错误......我希望相同的代码在两个数据库上都可以工作。至于省略转义部分(仅使用 LIKE '%'),这适用于两个数据库,但即使我可以省略转义(我相信我不能),我希望可以有不同的解决方案。 ..
【解决方案4】:

是否对每个输入或特定字符串都失败?问题可能不在于查询,而在于输入。如果有奇数个反斜杠,Oracle 可能会尝试转义不需要转义的内容。

例如,这是因为它转义了“%”:

select * from dual  where 'test' like '%'||'\'||'%' escape '\';

但这失败了,因为它试图逃避不需要转义的“a”:

select * from dual  where 'test' like '%'||'\a'||'%' escape '\';

你能在字符串传递给函数之前修改字符串并修复奇怪的反斜杠吗?

【讨论】:

  • 它看起来不像 someText 字符串那么远。该错误(尤其是空的'')表明反斜杠已被视为转义字符,并且在解析查询本身之前已丢失。
  • 我认为你是对的。我刚刚注意到我的代码生成 ORA-01424,而不是 ORA-01425。
  • 感谢 jonearles 的建议!但是,这只是一个 nvarchar2 字段问题。 select * from dual where 'dummy' like '%' escape '\';两者都适用,因为“dummy”字段是 varchar2。
【解决方案5】:

如果有人遇到同样的问题...我的问题是我正在处理“NVARCHAR2”字段。我在 oracle 论坛中收到了有关此问题的帮助 :)

这个查询:select * from dual where 'dummy' like '%' escape '\';

两者都适用,因为字段“dummy”是 varchar2。如果它是 nvarchar2,查询中可能(仅可能!)导致问题的部分将是“转义 '\'”部分(我的 oracle 9i 想要转义 '\',我的 oracle 10g 想要 '\\')。

为了克服这个问题,我没有使用 ORM 的自动生成代码,而是编写了一个存储过程(仅在我搜索字符串时),我在其中处理 nvarchar2 字段,如下所示: where TableName.ColumnName like N'%' || 'someText' || N'%' 转义 N'\'

它运行良好:)

然而,这并不能解释如何拥有相同的 NVARCHAR2 列和相同的 SQL 查询,如何通过两个 oracle 服务器(我本地 PC 上的 10g express 和 9i)对它们进行不同的处理——这仍然是一个问题.因此,对于遇到类似问题的任何人,最好知道这是否是 nvarchar2 问题(我不知道这可能是一个问题),然后尝试解决它。​​

【讨论】:

    猜你喜欢
    • 2017-06-24
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多