Snowflake存储过程复制至AWS S3时遇语法错误求助
问题解决:Snowflake存储过程拼接动态日期到S3文件名
错误原因
你的代码直接将GET_CURRENT_DATE变量(存储的是SELECT语句字符串)拼接到了COPY INTO的路径中,导致生成的SQL语法错误——路径变成了's3://bucket/dev/file_SELECT TO_VARCHAR(TO_DATE(CURRENT_DATE()::VARCHAR,'YYYY-MM-DD'),'MMDDYYYY').csv',Snowflake无法识别这种格式。
修正方案
需要先执行日期查询获取实际的格式化日期值,再将该值拼接到COPY语句的路径中。同时优化字符串转义和参数使用:
修正后的完整代码
CREATE OR REPLACE PROCEDURE PROC_S3_COPY("ENV" VARCHAR(16777216), "SCHEMA_ENV" VARCHAR(16777216)) RETURNS VARIANT LANGUAGE JAVASCRIPT EXECUTE AS OWNER AS $$ var return_rows = []; var GET_CURRENT_DATE = `SELECT TO_VARCHAR(CURRENT_DATE(), 'MMDDYYYY')`; -- 简化日期格式化语句 // 执行日期查询,获取格式化后的日期值 var dateResult = snowflake.execute({sqlText: GET_CURRENT_DATE}); dateResult.next(); var formattedDate = dateResult.getColumnValue(1); // 用实际日期值拼接COPY INTO语句 var COPY_TO_S3 = `COPY INTO 's3://bucket/${ENV}/file_${formattedDate}.csv' FROM ${SCHEMA_ENV}.my_table -- 使用传入的参数替代硬编码的schema CREDENTIALS=(AWS_KEY_ID='aws_key' AWS_SECRET_KEY='aws_secret') FILE_FORMAT = my_csv_file_format HEADER=TRUE SINGLE=TRUE MAX_FILE_SIZE=4900000000;`; try { // 执行COPY操作并获取结果 var copyResult = snowflake.execute({sqlText: COPY_TO_S3}); copyResult.next(); return_rows.push({rows_copied: copyResult.getColumnValue(1), target_file: `file_${formattedDate}.csv`}); return return_rows; } catch (err) { throw `PROC_S3_COPY执行异常: ${err.message} (错误代码: ${err.code})`; } $$;
关键修改点
- 获取实际日期值:执行日期查询后,通过
dateResult.next()和dateResult.getColumnValue(1)拿到格式化后的日期字符串(如04232023),而非直接拼接SELECT语句。 - 简化日期格式化:
TO_VARCHAR(CURRENT_DATE(), 'MMDDYYYY')可直接得到目标格式,无需多余类型转换。 - 利用传入参数:将存储过程的
ENV和SCHEMA_ENV参数用到路径和表名中,让存储过程适配不同环境。 - 修正字符串转义:Snowflake SQL中的字符串用单引号,在JavaScript模板字符串中直接使用单个单引号即可,无需重复转义。
- 优化错误信息:在异常中返回更详细的错误内容,便于排查问题。
验证方式
调用存储过程时会自动生成带当前日期的文件名:
CALL PROC_S3_COPY('dev', 'my_schema');
执行成功后,S3中会生成类似file_04232023.csv的文件。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

