在过程中执行动态插入

问题描述 投票:0回答:1

我是 Postgres 新手,正在尝试创建将多个表中的数据插入到单个表中的代码。

所有源表的名称都以“B3_HIST_”开头,仅年份不同(它们的命名范围为“B3_HIST_2015”到“B3_HIST_2023”)。

我使用 3 个变量,连接名称并在循环中使用它们,如下所示:

create or replace procedure dbo.SP_B3_HIST ()
language plpgsql
AS $$
declare
    nametab TEXT := 'dbo.B3_HIST_';
    startyr INTEGER := 2015;
    lastyr INTEGER := 2023;
begin
    while startyr <= lastyr  loop

        INSERT INTO TEMP1 SELECT * FROM (nametab || startyr )
        startyr = startyr  + 1
    END LOOP;
END; $$

问题:

ERROR: string between dollars did not end in or near "$$
declare
    nametab TEXT := 'dbo.B3_HIST_'"
LINE 3: AS$$
^

如何正确执行此操作?

postgresql plpgsql dynamic-sql
1个回答
0
投票

可以循环为每个源表运行单独的

INSERT
。 (就像大桌子和每张桌子后面的
COMMIT
?)

通常,构建单个语句(使用纯 SQL)并执行更简单、更快:

CREATE OR REPLACE PROCEDURE dbo.sp_b3_hist()
  LANGUAGE plpgsql AS
$proc$
DECLARE
   nametab text := 'dbo.b3_hist_';  -- lower case
   startyr int := 2015;
   lastyr  int := 2023;
BEGIN
-- RAISE NOTICE '%', (  -- debug first?
   EXECUTE (
   SELECT E'INSERT INTO temp1 \n'
       || string_agg('TABLE ' || nametab || g, E'\nUNION ALL ')
   FROM   generate_series(startyr, lastyr) g
   );
END
$proc$;

CALL dbo.sp_b3_hist();

相关:

如果是一次性操作,请使用

DO
命令而不是持久化过程。

或者在 psql 中使用

\gexec

参见:

避免在 Postgres 中混合大小写标识符,让您的生活更轻松。

© www.soinside.com 2019 - 2024. All rights reserved.