我有下面的一段代码,它做了下面的事情
- 生成一组字符串列名时,提供了一个日期范围,这只是日期之间的范围
- 然后在另一个函数中使用此函数生成动态查询字符串
- 下一个生成的动态查询字符串与
EXECUTE
一起使用
由于我注意到EXECUTE
语句出现语法错误,我已经尝试了不同的美元报价变体,但没有成功。
DROP EXTENSION IF EXISTS tablefunc;
CREATE EXTENSION IF NOT EXISTS tablefunc;
DROP FUNCTION IF EXISTS app_public.generate_date_columns(p_from_date DATE, p_to_date DATE);
-- Step 2: Create a function that generates the dynamic SQL query
CREATE OR REPLACE FUNCTION app_public.generate_date_columns(p_from_date DATE, p_to_date DATE)
RETURNS TEXT AS $$
DECLARE
column_names TEXT := '';
pay_date DATE;
BEGIN
-- Generate column names and select columns
FOR pay_date IN SELECT generate_series(p_from_date, p_to_date, '1 day'::interval)::DATE LOOP
column_names := column_names || format('"%s" INT,', pay_date);
END LOOP;
-- Remove the trailing commas
column_names := substr(column_names, 1, length(column_names) - 1);
RAISE NOTICE 'Columns: %s', column_names;
RETURN column_names;
END
$$ LANGUAGE plpgsql;
SELECT app_public.generate_date_columns('2023-05-30'::DATE, '2023-06-05'::DATE);
DROP FUNCTION IF EXISTS app_public.incentive_per_line(DATE, DATE);
CREATE OR REPLACE FUNCTION app_public.incentive_per_line(p_from_date DATE, p_to_date DATE)
RETURNS SETOF RECORD AS $$
DECLARE
column_names TEXT;
v_dynamic_query TEXT;
BEGIN
SELECT app_public.generate_date_columns(p_from_date, p_to_date) INTO column_names;
SELECT FORMAT($tag$'SELECT * FROM crosstab($ct$'SELECT op.line_no::SMALLINT, pay.payout_date::DATE, pay.amount::INT AS incentive
FROM app_public.operators AS op INNER JOIN app_public.payouts AS pay ON pay.oid = op.id
WHERE pay.payout_date >= date($from$'%s'$from$) AND pay.payout_date <= date($to$'%s'$to$)'$ct$) AS ct(ln SMALLINT, $cn1$%s$cn1$)'$tag$, p_from_date, p_to_date, column_names)
INTO v_dynamic_query;
RAISE NOTICE '%s', v_dynamic_query;
EXECUTE v_dynamic_query;
END
$$ LANGUAGE plpgsql;
select app_public.incentive_per_line('2023-05-30'::DATE, '2023-06-05'::DATE);
我希望动态查询能够成功执行,并且没有任何语法错误。另外,如果你能帮助我改善这种美元报价的经验,我将不胜感激。
语法错误:
[42601] ERROR: syntax error at or near "'SELECT * FROM crosstab($ct$'" Where: PL/pgSQL function app_public.incentive_per_line(date,date) line 16 at EXECUTE
1条答案
按热度按时间xggvc2p61#
错误消息显示错误语法,具体地说,
SELECT
之前的单个'
。SELECT
语句已经被$ct$
引用,因此额外的单个'
是字符串的一部分,而不是引用字符串。