使用DbVisualizer/Redshift创建函数遇语法错误求助
问题解决:Redshift创建business_days_between函数语法错误
你的错误根源是混淆了Redshift中SQL语言函数和PL/pgSQL语言函数的语法:
- 你用了
DECLARE/BEGIN/END这类PL/pgSQL的块结构,但最后指定了LANGUAGE sql,这会直接触发语法报错。 - Redshift的SQL语言函数只能是单个表达式,不能包含变量声明和流程控制逻辑;如果要使用变量和块结构,必须指定
LANGUAGE plpgsql。
修复后的两种实现方式
方式1:PL/pgSQL语言(保留变量逻辑)
把LANGUAGE sql改为LANGUAGE plpgsql,同时调整代码格式提升可读性:
CREATE OR REPLACE FUNCTION business_days_between(start_date DATE, end_date DATE) RETURNS INTEGER IMMUTABLE AS $$ DECLARE total_days INTEGER := DATEDIFF(day, start_date, end_date); weekdays INTEGER := total_days - (DATEDIFF(week, start_date, end_date) * 2); holidays INTEGER := (SELECT COUNT(*) FROM temp.holidays WHERE holiday_date BETWEEN start_date AND end_date); BEGIN RETURN weekdays - holidays; END;$$ LANGUAGE plpgsql;
方式2:SQL语言(单表达式实现)
如果偏好使用SQL语言,可把所有逻辑合并为单个查询:
CREATE OR REPLACE FUNCTION business_days_between(start_date DATE, end_date DATE) RETURNS INTEGER IMMUTABLE AS $$ SELECT DATEDIFF(day, start_date, end_date) - (DATEDIFF(week, start_date, end_date) * 2) - (SELECT COUNT(*) FROM temp.holidays WHERE holiday_date BETWEEN start_date AND end_date); $$ LANGUAGE sql;
额外注意事项
- 若
temp.holidays表的数据会发生变动,建议把IMMUTABLE改为STABLE——IMMUTABLE要求函数结果仅由输入参数决定,不依赖外部数据变化,而STABLE允许函数依赖在事务内不变的外部数据。
内容的提问来源于stack exchange,提问作者Cece Topham
相关产品推荐
相关产品推荐

