2

这是需要执行的代码块:

DECLARE
STR CLOB;
BEGIN

STR := ' CREATE TABLE TNAME AS

SELECT ... FROM INPUT_TABLE IP
WHERE ((IP.DATE_FIELD = TO_DATE('12.08.2013', 'DD.MM.sYYYY'))) ' ;

EXECUTE IMMEDIATE (STR);

END;

这个块是用java代码形成的。在执行时,这会抛出异常org.springframework.jdbc.BadSqlGrammarException。但是当我更改TO_DATE('12.08.2013', 'DD.MM.sYYYY')TO_DATE(''12.08.2013'', ''DD.MM.sYYYY'')它时,它会成功执行。

以下是我的问题:

1)为什么当我使用单引号时会抛出异常?

2)单引号和双“单引号”有什么区别?

3)如果我总是使用双“单引号”,会有什么后果吗?

4

2 回答 2

4

来自关于文本文字的 Oracle 文档:

在语法的顶部分支中:

  • c是用户字符集的任何成员。文字中的单引号 (') 必须以转义字符开头。要在文字中表示一个单引号,请输入两个单引号。

在您的原始版本中,紧接在 之前的单引号12.08.2013被视为该字符串的结尾 - 它怎么知道以其他方式对待它?then 变成了12.08一个数字,但它不在一个有用的地方,所以解析器不知道如何处理它,所以你得到一个错误。

在第二个版本中,您已经对作为实际文本值一部分的引号进行了转义,因此 Oracle 知道它们是文本的一部分,而不是标记文本的结尾。当它到达分号之前的唯一单引号时,它会将视为字符串的结尾,这就是您想要的。

create正如@Parado 所说,尝试显示转义引用的版本,您会看到它以一种可以直接运行的形式出现,转义的单引号作为您的语句的一部分本身作为字符串出现 。

您确实需要转义所有单引号,但您可能会发现替代引用语法更容易,如文档中的第二个分支中所述。在你的情况下,这将是:

STR := q'[ CREATE TABLE TNAME AS
SELECT ... FROM INPUT_TABLE IP
WHERE ((IP.DATE_FIELD = TO_DATE('12.08.2013', 'DD.MM.sYYYY'))) ]';

这使得引用的文本更易于阅读,您不必担心捕获和转义其中的所有单引号。你只需要确保你选择了一个没有出现在文本中的引号分隔符。显示它看起来与您的转义引用版本完全相同。

于 2013-08-07T08:31:35.923 回答
1

我不想直接问你的问题。了解问题的最佳方法是自己测试。代替

EXECUTE IMMEDIATE (STR);

请输入代码

dbms_output.put_line(STR);

之后,使用单引号和双引号运行您的程序。它将返回 sql 命令。尝试运行返回的命令,希望你能看到并了解它是如何工作的。

注意:不要忘记设置SET SERVEROUTPUT ON

于 2013-08-07T07:17:27.087 回答