Oracle数据库SQL字符串转义:动态生成gather_table_stats语句出错
问题分析
原SQL语句存在四处核心错误:
- 单引号转义不符合Oracle规则:Oracle字符串常量中要输出1个单引号,需要连续写2个单引号进行转义,原语句中SCHEMA两侧的单引号、
trunc(sysdate, 'MM')中的'MM'、to_char的'YYYY-MM'格式符的单引号都没有正确转义,会直接触发语法错误。 - 动态拼接逻辑错误:你把负责生成年月的
to_char函数写在了单引号包裹的静态字符串内部,导致该函数不会被Oracle执行计算,只会作为普通文本输出,无法得到动态的年月后缀。 - 日期格式符错误:
to_char的格式符写为了'YYYY-MM',输出会是横杠分隔的年月,和你期望的下划线分隔的2021_07格式不符。 - 你给出的期望输出存在语法错误:
gather_table_stats的参数括号在表名后提前闭合了,正确写法是所有入参(包括schema名、表名、cascade、no_invalidate参数)都应该放在同一个参数括号内。
正确写法
如果需要生成语法正确的统计信息收集语句,使用以下写法:
select 'BEGIN dbms_stats.gather_table_stats(''SCHEMA'', ''TABLENAME_' || to_char(trunc(sysdate, ''MM''), ''YYYY_MM'') || '' , cascade => true, no_invalidate => false); END;' from dual;
如果要严格匹配你给出的期望输出格式(保留表名后的多余闭合括号),使用以下写法:
select 'BEGIN dbms_stats.gather_table_stats(''SCHEMA'', ''TABLENAME_' || to_char(trunc(sysdate, ''MM''), ''YYYY_MM'') || '''), cascade => true, no_invalidate => false); END;' from dual;
输出示例(当前月份为2024年5月时)
语法正确的输出:
BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_2024_05' , cascade => true, no_invalidate => false); END;
匹配你给出的期望格式的输出:
BEGIN dbms_stats.gather_table_stats('SCHEMA', 'TABLENAME_2024_05'), cascade => true, no_invalidate => false); END;
转义逻辑说明
- 静态字符串开头和结尾用单个单引号包裹,字符串内部要输出
'的位置全部替换为'',比如要输出'SCHEMA',在静态字符串中就要写为''SCHEMA'' - 动态计算的
to_char部分放在所有静态字符串之外,通过||和前后的静态字符串拼接,to_char内部用到的单引号参数同样需要转义为两个连续单引号
内容的提问来源于stack exchange,提问作者Mladen Nikolic
相关产品推荐
相关产品推荐

