关于动态SQL中单引号使用的技术咨询及错误排查
PL/SQL动态SQL单引号问题梳理
一、第一段代码的多单引号逻辑
单引号转义规则
在PL/SQL的字符串字面量中,要生成一个实际的单引号,必须用两个连续的单引号('')来转义。这是因为单引号本身用来标记字符串的起止,双写单引号是告诉编译器:这是一个普通的单引号,不是字符串的结束符。
第一段代码的拆解
以核心拼接逻辑为例:
L_SQL := 'SELECT COUNT(1) FROM TABLE A WHERE COL1 = ''' || V_1 || ''' -- where col1 = ''2021YEAR_REPORT'' AND COL2 LIKE ''%' || V_2 || ''' -- and col2 like ''%202302'' AND COL3 = ''' || V_4 || '''';
我们拆解WHERE COL1 = ''' || V_1 || '''这部分:
- 第一个字符串片段
'WHERE COL1 = ''':前两个''转义出一个实际单引号,第三个'结束当前片段,最终生成WHERE COL1 = ' || V_1 ||:拼接变量V_1的实际值(比如2021YEAR_REPORT)- 第二个字符串片段
''':第一个'开启新片段,里面的''转义出一个实际单引号,最后一个'结束片段,最终生成'
拼接后最终的SQL片段就是WHERE COL1 = '2021YEAR_REPORT',和注释效果一致。
阅读与编写技巧
- 阅读:把连续两个单引号看成一个实际单引号,再通过单个
'区分字符串的起止。比如'''可以理解为「用转义单引号组成的字符串片段」,用来给变量值前后加引号。 - 编写:如果要把变量作为字符串常量嵌入动态SQL,直接用
''' || 变量名 || '''格式,本质是用转义单引号分别包裹变量值的前后。
二、第二段代码的PLS-00103错误原因及修复
错误根源
错误行:
sql_1 := 'select count(1) from table_1 a where a.col1 ='|| ''v1''; -- error
这里的''v1''存在两个问题:
- 语法错误:
''是转义单引号,之后的v1没有被字符串包裹,PL/SQL会将其视为无效标识符,直接触发PLS-00103(意外符号)。 - 逻辑错误:就算语法合法,
''v1''会被解析成字符串'v1',拼接后SQL变成where a.col1 ='v1',是查询col1等于字符串v1,而非变量v1的实际值。
修复写法
写法一:用单引号转义包裹变量
按照第一段的规则,正确拼接变量并添加单引号:
sql_1 := 'select count(1) from table_1 a where a.col1 = ''' || v1 || '''';
拼接后SQL会变成where a.col1 = '变量v1的值',符合需求。
写法二:用绑定变量(推荐)
完全避免单引号转义的麻烦,同时提升性能、防止SQL注入:
sql_1 := 'select count(1) from table_1 a where a.col1 = :1'; EXECUTE IMMEDIATE sql_1 INTO v_new USING v1;
:1是绑定变量占位符,USING v1表示把变量v1的值传入占位符,编译器会自动处理类型和引号问题。
内容的提问来源于stack exchange,提问作者LSY FDC
相关产品推荐
相关产品推荐

