问题
Here is a block of code which needs to be executed:
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;
This block is formed in java code. On execution, this throws exception org.springframework.jdbc.BadSqlGrammarException. But when i change TO_DATE('12.08.2013', 'DD.MM.sYYYY')
to TO_DATE(''12.08.2013'', ''DD.MM.sYYYY'')
it executes successfully.
Here are my questions:
1) Why does it throw exception when i am using single quote?
2) What is difference between single quote and double 'single quotes'?
3) If i always use double 'single quotes', will there be any consequences?
回答1:
From the Oracle documentation on text literals:
In the top branch of the syntax:
- c is any member of the user's character set. A single quotation mark (') within the literal must be preceded by an escape character. To represent one single quotation mark within a literal, enter two single quotation marks.
In your original version, the single quote immediately before the 12.08.2013
is treated as the end of that string - how would it know to treat it any other way? The 12.08
then becomes a number, but it's not in a useful place, so the parser doesn't know what to do with it, so you get an error.
In the second version you've escaped the quotes that are part of the actual text value, so Oracle knows they are part of the text, not marking the end of it. When it reaches the lone single quote before the semi-colon it sees that as the end of the string, which is what you want.
As @Parado says, try displaying the escape-quoted version and you'll see that it appears in a form that you could run directly, with the escaped single quotes appearing as strings in their own right as part of your create
statement.
You do need to escape all the single quotes, but you might find the alternative quoting syntax easier, as described in the second branch in the documentation. In your case that would be:
STR := q'[ CREATE TABLE TNAME AS
SELECT ... FROM INPUT_TABLE IP
WHERE ((IP.DATE_FIELD = TO_DATE('12.08.2013', 'DD.MM.sYYYY'))) ]';
This makes the quoted text literal easier to read and you don't have to worry about catching and escaping all the single quotes within it. You just need to make sure you pick a quote delimiter that doesn't appear in the text. Displaying that will look exactly the same as your escape-quoted version.
回答2:
I don't want to ask your question directly. The best way to understand your problem is test it yourself. Instead of
EXECUTE IMMEDIATE (STR);
please type the code
dbms_output.put_line(STR);
After that run your procedure with one quote and double quote. It will return sql commands. Try to run returned commands than I hope you will see and idea how it works.
NOTE: Don't forget to set SET SERVEROUTPUT ON
来源:https://stackoverflow.com/questions/18096740/use-of-single-quote-and-double-single-quote-in-pl-sql-block