【问题标题】:Why is SET DEFINE OFF not working for the colon (:) character?为什么 SET DEFINE OFF 对冒号 (:) 字符不起作用?
【发布时间】:2017-10-08 03:37:49
【问题描述】:

我有一个试图通过 sqlplus 运行的脚本。在脚本的顶部,我设置了“SET DEFINE OFF”。但是,当我运行它时,我收到了这个错误:

SP2-0552:绑定变量“CHANDAWALA”未声明。

我相信这种情况正在发生,因为我有几个更新语句,它们在这样的字符串中包含冒号:

UPDATE ADDRESS SET ADDRESS_STREET_LINE1 = 'Moh: Chandawala'...
UPDATE ADDRESS SET ADDRESS_STREET_LINE1 = 'Moh:chandawala'...

所以它将它们视为绑定变量。我的印象是 SET DEFINE OFF 会使其将引用字符串中的任何内容视为字符,而不是解释其中的任何内容,包括感知的绑定变量。

显然不是这样 - 那么在这种情况下,我应该怎么做?我必须手动转义这些吗?

谢谢。

编辑-When or Why to use a "SET DEFINE OFF" in Oracle Database 上发布的问题对我没有帮助,因为该人试图逃避 & 符号以进行变量替换,而不是将冒号作为绑定变量。我正在寻找一种方法来告诉客户端忽略引用字符串中的任何内容(包括冒号)。

编辑-好的,听起来Oracle不应该将其解释为引号内的绑定变量。所以现在的问题是,它为什么要这样做?

【问题讨论】:

  • 我看过那篇文章,但没有提到绑定变量和转义冒号。除非我错过了什么……
  • :chandawala 用单引号括起来时不应被解释为绑定变量。
  • 谢谢 - 那么我想问题是为什么它试图将其解释为绑定变量呢?事实上,我确实将它用单引号括起来。我在问题的代码块中粘贴的正是我的脚本的外观,脚本中没有其他地方有“chandawala”这个词。
  • 您是否有可能使用了错误类型的引号 - 如果您有反引号或智能引号或其他东西(可能是从 Word 或类似内容中复制和粘贴查询),那么您会收到此错误。您发布的内容没有问题,但您是否从代码中复制或重新输入以进行发布?
  • 如果语句本身运行良好,但不是作为较大脚本的一部分,则直接怀疑应该是脚本 REST 中的错误引用(在这些 UPDATE 语句之前)。很多时候,像 O'Meara 这样的名称的撇号没有正确转义的结果。

标签: oracle sqlplus


【解决方案1】:

Set Define Off 是一个 SQLPlus 命令,它阻止 SQLPlus 将 & 视为特殊字符。 & 也是 SQLPlus 特有的,在它之外没有任何意义。

defineon 时,SQLPlus 将替换变量替换为实际值,然后将其传递给 Oracle SQL 引擎。

另一方面,: 是真正的绑定变量,只有 Oracle SQL 引擎才能识别并查找要绑定的值。 : 不被 SQLPlus 识别为绑定元字符,因此被传递给 SQL 引擎。

【讨论】:

  • 所以你是说基本上没有办法关闭它?而且,根据 Nicholas Krasnov 的评论,如果它被括在引号中,则无论如何都不应该将其解析为绑定变量。我不确定为什么会这样……谢谢。
  • 在您的第二段中,我会说它“替换 substitution 变量”以避免与绑定变量混淆,因为它们是非常不同的东西?
  • @AlexPoole 你是对的。更新。但不确定为什么 Oracle 将单引号内的 : 视为绑定变量。起初我并没有真正看到这一点。我认为 OP 方面存在一些问题。
  • 我不怀疑有,但我想找到它:)
  • 我认为正如我们在上面的主要 cmets 字符串中所讨论的那样,我一定在某处有过流氓评论。我从 UPDATE 语句中取出了一些多余的字段,现在它可以工作了。
【解决方案2】:

我无法复制您的问题。我创建了一个名为 dual 的表,其中包含单个字符的列。当我尝试运行更新语句时,不允许替换。

SQL> UPDATE brianl.dually
  2         SET dummy   = ':x';
       SET dummy   = ':x'
                     *
ERROR at line 2:
ORA-12899: value too large for column "BRIANL"."DUALLY"."DUMMY" (actual: 2,
maximum: 1)

您是否尝试过使用串联?

UPDATE ADDRESS SET ADDRESS_STREET_LINE1 = 'Moh' || ':' || Chandawala'

【讨论】:

  • 我认为复制我认为的问题是尝试更新两个字段,但第一个字段的值包含未转义的单引号。那么 Oracle 会认为第二个字段值实际上是一个绑定变量。我希望这是有道理的(请参阅我原始帖子的评论主题)。有趣的是,您提到了串联,我的老板也建议这样做,但我在尝试之前找到了一种解决方法。无论如何,谢谢。
猜你喜欢
  • 2011-12-04
  • 1970-01-01
  • 2010-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 2011-01-24
相关资源
最近更新 更多