postgresql 尝试执行包含美元引号的动态查询时出现语法错误,以转义嵌套的单引号

w8ntj3qf  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(149)

我有下面的一段代码,它做了下面的事情

  • 生成一组字符串列名时,提供了一个日期范围,这只是日期之间的范围
  • 然后在另一个函数中使用此函数生成动态查询字符串
  • 下一个生成的动态查询字符串与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
xggvc2p6

xggvc2p61#

错误消息显示错误语法,具体地说,SELECT之前的单个'

[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

SELECT语句已经被$ct$引用,因此额外的单个'是字符串的一部分,而不是引用字符串。

相关问题