这是一段需要执行的代码:
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)如果我总是使用双“单引号”,会有任何后果吗?
答案 0 :(得分:4)
来自text literals上的Oracle文档:
在语法的顶部分支中:
- c 是用户角色集的任何成员。文字中的单引号(')必须以转义字符开头。 要在文字中表示单个引号,请输入两个 单引号。
在原始版本中,紧接12.08.2013
之前的单引号被视为该字符串的结尾 - 如何以任何其他方式处理它? 12.08
然后变成一个数字,但它不在一个有用的地方,所以解析器不知道如何处理它,所以你得到一个错误。
在第二个版本中,您已经转义了作为实际文本值一部分的引号,因此Oracle知道它们是文本的一部分,而不是标记它的结尾。当它在分号前达到单引号时,它会将 视为字符串的结尾,这就是你想要的。
正如@Parado所说,尝试显示转义引用的版本,您会看到它出现在您可以直接运行的表单中,转义的单引号作为您自己的一部分显示为字符串{{{ 1}}陈述。
您确实需要转义所有单引号,但您可能会更容易找到替代引用语法,如文档中的第二个分支所述。在你的情况下:
create
这使得引用的文本文字更容易阅读,您不必担心捕获和转义其中的所有单引号。您只需要确保选择一个未出现在文本中的引号分隔符。显示与您的转义引用版本完全相同的内容。
答案 1 :(得分:1)
我不想直接问你的问题。理解您的问题的最佳方法是自己测试。而不是
EXECUTE IMMEDIATE (STR);
请输入代码
dbms_output.put_line(STR);
之后用一个引号和双引号运行你的程序。它将返回sql命令。尝试运行返回的命令,但希望你能看到并了解它是如何工作的。
注意:不要忘记设置SET SERVEROUTPUT ON