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;
$$;
我正在尝试对 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;
$$;