这是需要执行的代码块:
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'')它时,执行成功。
TO_DATE('12.08.2013', 'DD.MM.sYYYY')
TO_DATE(''12.08.2013'', ''DD.MM.sYYYY'')
这是我的问题:
1)为什么在我使用单引号时会引发异常?
2)单引号和双引号“单引号”有什么区别?
3)如果我始终使用双“单引号”,会不会有任何后果?
从Oracle文档中获取文本文字:
在语法的顶部分支中: c 是用户字符集的任何成员。文字中的单引号(’)必须在前面加上转义字符。要在文字中表示一个单引号,请输入两个单引号。
在语法的顶部分支中:
在您的原始版本中,紧接在之前的单引号12.08.2013被视为该字符串的结尾- 如何知道以其他方式对其进行处理?在12.08随后成为了许多,但它不是一个有用的地方,所以解析器不知道怎么用它做什么,所以你得到一个错误。
12.08.2013
12.08
在第二个版本中,您转义了实际文本值中包含引号的内容,因此Oracle知道它们是文本的一部分,而不是标记文本的结尾。当它到达分号前的唯一单引号它认为 是 为字符串,结束这就是你想要的。
就像@Parado所说的那样,尝试显示用转义引号引起来的版本,您会看到它以可以直接运行的形式出现,在create语句中,转义的单引号本身以字符串形式出现 。
create
您确实需要转义所有单引号,但是您可能会发现替代引号语法更容易,如本文档第二个分支中所述。您的情况是:
STR := q'[ CREATE TABLE TNAME AS SELECT ... FROM INPUT_TABLE IP WHERE ((IP.DATE_FIELD = TO_DATE('12.08.2013', 'DD.MM.sYYYY'))) ]';
这使得带引号的文字文字更易于阅读,并且您不必担心捕获和转义其中的所有单引号。您只需要确保选择的引号定界符没有出现在文本中即可。显示的内容将与转义引用的版本完全相同。