postgresql,无法识别记录数据类型中的列

postgresql, could not identify column in record data type

我正在尝试对 Postgresql 使用动态 SQL。我坚持尝试在另一个 EXECUTE 语句中使用 db_row RECORD 中的 id 字段。字段 id 设置在记录变量中,但我仍然收到错误:

ERROR:  could not identify column "id" in record data type
LINE 1: SELECT .id FROM audit.portfolio WHERE alter_type = 'INSERT...
               ^
QUERY:  SELECT .id FROM audit.portfolio WHERE alter_type = 'INSERT' AND id = .id
CONTEXT:  PL/pgSQL function inline_code_block line 14 at EXECUTE

这是我的数据和测试函数:

CREATE TABLE IF NOT EXISTS public.portfolio
(
  id   INTEGER NOT NULL,
  name CHARACTER VARYING,
  CONSTRAINT portfolio_pkey PRIMARY KEY (id)
)
WITH (OIDS = FALSE);

CREATE TABLE IF NOT EXISTS audit.portfolio
(
  alter_type TEXT,
  id         INTEGER NOT NULL,
  name       CHARACTER VARYING,
  CONSTRAINT portfolio_pkey PRIMARY KEY (id)
)
WITH (OIDS = FALSE
);

INSERT INTO public.portfolio (id, name) VALUES (1, 'NAME 1'), (2, 'NAME 2');

-- temp function
DO $$
DECLARE
  db_row RECORD;
  pk_val BIGINT;

BEGIN

  FOR db_row IN EXECUTE format(
      'SELECT *, 100 AS created_by_id, %L::TIMESTAMP AS creation_time FROM public.%I ORDER BY %I',
      '2014-01-01 00:00:00', 'portfolio', 'id', 'id')
  LOOP
    RAISE NOTICE 'db_row.id: %', db_row.id;
    EXECUTE
    format(
        'SELECT .%I FROM audit.%I WHERE alter_type = %L AND %I = .%I',
        'id', -- this will be dynamic and change when table change
        'portfolio', -- this will be dynamic and change when table change
        'INSERT',
        'id', -- this will be dynamic and change when table change
        'id' -- this will be dynamic and change when table change
    )
    INTO pk_val
    USING db_row;
    RAISE NOTICE 'pk_val: %', pk_val;
  END LOOP;
END$$;

似乎 postgres EXECUTE ... USING db_row 没有看到 db_row 的完整结构,就像来自 porfolio table 的行一样。

我的最终目标是创建将采用任何现有 table 名称的函数 这样做:

EXECUTE
    format(
        'SELECT .%I FROM audit.%I WHERE alter_type = %L AND %I = .%I',
        'primary_key_col', 
        'table_name', 
        'INSERT',
        'primary_key_col', 
        'primary_key_col'
    )
    INTO pk_val
    USING db_row

如何告诉 postgres 在这个 EXECUTE 语句中使用 db_row.id 值?

问题是您将 record 类型的参数 (db_row) 传递给 SQL 语句,但是这样的值对于 [=19 没有已知的结构=] 引擎。您甚至不能将其转换为 table 类型。

我能想到的一个丑陋的解决方法是将记录转换为其文本表示形式(通过调用类型输出函数工作),然后将测试转换为所需的 table 类型。

这是说明我的意思的示例代码:

DO $$
DECLARE
   r record;
   n name;
BEGIN
   /* find all tables with a column "oid" */
   FOR r IN
      SELECT t.*
         FROM pg_class t
              JOIN pg_attribute a ON a.attrelid = t.oid
         WHERE a.attname = 'oid'
   LOOP
      /* get the table name */
      EXECUTE format(
                 'SELECT (::text::%s).relname',
                 'pg_class'
              ) INTO n USING r;
      RAISE NOTICE 'Table name: %', n;
   END LOOP;
END;
$$;