在 SELECT 生成的行上循环 - 循环变量不存在?

Loop on rows produced by SELECT - looping variable does not exist?

函数创建的很好,但是当我尝试执行它时,我得到这个错误:

ERROR: relation "column1" does not exist
SQL state: 42P01
Context: SQL statement "ALTER TABLE COLUMN1 ADD COLUMN locationZM geography (POINTZM, 4326)"
PL/pgSQL function addlocationzm() line 6 at SQL statement

代码:

CREATE OR REPLACE FUNCTION addlocationZM() 
RETURNS void AS
$$
    DECLARE
        COLUMN1 RECORD;
    BEGIN
        FOR COLUMN1 IN SELECT f_table_name FROM *schema*.geography_columns WHERE type LIKE 'Point%' LOOP
            ALTER TABLE COLUMN1 ADD COLUMN locationZM geography (POINTZM, 4326); 
        END LOOP;
    END;
$$
LANGUAGE 'plpgsql';

SELECT addlocationZM()

我可能只是太笨了,但我已经在这方面做了一段时间了,但我就是不明白。 SELECT f_table_name ... 语句自己执行 returns 单列 58 行,每行都是我模式中的一个 table 的名称。这样做的想法是在 SELECT.

拉出的每个 table 中创建一个新列,类型为 PointZM

该函数将像这样工作:

CREATE OR REPLACE FUNCTION addlocationZM() 
  RETURNS void AS
$func$
DECLARE
   _tbl text;
BEGIN
   FOR _tbl IN
      SELECT f_table_name FROM myschema.geography_columns WHERE type LIKE 'Point%'
   LOOP
      EXECUTE
      format('ALTER TABLE %I ADD COLUMN location_zm geography(POINTZM, 4326)', _tbl); 
   END LOOP;
END
$func$  LANGUAGE plpgsql;

请注意我是如何使用一个简单的 text 变量来简化问题的。您不需要 record 开头。

如果是一次性操作,请使用DO命令而不是创建函数:

DO
$do$
BEGIN
   EXECUTE (
      SELECT string_agg(
                format(
                   'ALTER TABLE %I ADD COLUMN location_zm geography(POINTZM, 4326);'
                  , f_table_name)
              , E'\n')
      FROM   myschema.geography_columns
      WHERE  type LIKE 'Point%'
      );
END
$do$;

这是为单个 EXECUTE.

连接由所有命令(用 ; 分隔)组成的单个字符串

,特别是当您不熟悉 plpgsql 和动态 SQL 时,只需生成命令,copy/paste 结果并作为第二步执行:

SELECT 'ALTER TABLE '
     || quote_ident(f_table_name)
     || ' ADD COLUMN locationZM geography(POINTZM, 4326);'
FROM   myschema.geography_columns
WHERE  type LIKE 'Point%';

(这次演示quote_ident()。)

相关:

  • Table name as a PostgreSQL function parameter

旁白:不带引号的 CaMeL 大小写标识符,如 locationZM 或您的函数名称 addlocationZM 可能不是一个好主意:

  • Are PostgreSQL column names case-sensitive?