Postgres PL/pgSQL存储过程format内COPY动态传时间条件报错如何解决
问题修正方案
你代码的核心错误是format()函数的使用方法不符合规范,且拼接的动态SQL存在语法缺口:
format()的第一个参数必须是完整的格式化模板,动态内容需要通过占位符填充,你将时间参数直接拆分到模板字符串的位置,同时时间常量没有包裹单引号,会导致生成的SQL语法非法- 拼接的SQL缺少必要空格,会出现
COPY(select、)to这类关键字连写的错误,PostgreSQL无法识别
修正后的完整代码
CREATE OR REPLACE PROCEDURE public.csv_test0002() LANGUAGE plpgsql AS $$ DECLARE sDate varchar; DEST varchar; sFromTime varchar(150); sToTime varchar(150); BEGIN sDate := to_char(current_timestamp, 'YYYY-MM-DD_HH24_MI_SS'); DEST := concat('Filename_',sDate); sFromTime := TO_CHAR(current_timestamp - interval '15 minutes', 'YYYY-MM-DD HH24:MI:SS'); sToTime := TO_CHAR(current_timestamp, 'YYYY-MM-DD HH24:MI:SS'); EXECUTE format( 'COPY (select avg(ptvalue) as ptvalue from pro_opc where ptname = ''OPC_SR'' and pttime between %L and %L) TO %L CSV HEADER', sFromTime, sToTime, 'D:\\' || DEST || '.csv' ); END $$;
修改说明
- 模板中使用
%L作为动态参数的占位符,format()会自动为字符串类型参数添加单引号、处理转义字符,不需要手动拼接引号,避免语法错误和SQL注入风险 - 补全了SQL语句中必要的空格,避免关键字连写
- Windows路径的反斜杠做了转义处理,改为
\\避免被识别为转义字符 - 所有动态参数都放到
format()的后续参数列表中,符合函数调用规范
如果你的pttime字段是timestamp类型,也可以直接传递timestamp类型的参数不需要转成字符串,只需要对应调整变量类型即可,兼容性更好。
内容的提问来源于stack exchange,提问作者Joyal Joy
相关产品推荐
相关产品推荐

