我的主要目的实际上是,过滤所有表名称中包含“Messdaten”(例如“ID:843063334 CH:0001 Messdaten”)并使用“create table as”命令创建新表格作为“Backup_Messdaten1” ,'Backup_Messdaten2'等
首先,我试图存储所有表名而不进行过滤(可能有一种方法可以检索所有表名,通过sql查询包含'Messdaten',我不知道),然后存储包含' Messdaten'进入另一个数组并在'create table as'命令中使用该新数组。
但正如我所说,我的第一个目标是将所有表名存储到一个数组中;
代码本身;
CREATE OR REPLACE FUNCTION retrieve()
RETURNS text[] AS
$BODY$DECLARE
tbl_names text[];
BEGIN
tbl_names := array(SELECT table_name FROM information_schema.tables WHERE
table_schema='public' AND table_type='BASE TABLE');
SELECT tbl_names[i] FROM generate_subscripts(tbl_names, 1) g(i);
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION retrieve()
OWNER TO postgres;
但是对于上面的代码,我收到了这样的错误;
错误;
ERROR: could not find array type for data type information_schema.sql_identifier
SQL state: 42704
Context: SQL statement "SELECT array(SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE')"
PL/pgSQL function retrieve() line 4 at assignment
你知道它有什么问题吗?通过我解释我的主要目的的方式,如果你指出我正确的方向,我会很感激。
答案 0 :(得分:3)
SELECT array_agg(table_name::text)
FROM information_schema.tables
WHERE table_schema='public' AND table_type='BASE TABLE';
您需要将表名转换为text
。子查询是不必要的,您需要使用array_agg
而不是array
伪函数。
我个人认为你不明白为什么需要将它们聚合成一个数组。我只是:
DECLARE
tablename text;
BEGIN
FOR tablename IN
SELECT table_name FROM information_schema.tables
WHERE table_schema='public' AND table_type='BASE TABLE'
AND ... my extra filters here ...
LOOP
EXECUTE format('CREATE TABLE %I AS TABLE %I', tablename || '_backup', tablename);
END LOOP;
END;
答案 1 :(得分:2)
您的代码包含更多错误 - 基本错误缺少任何RETURN语句(对于PL / pgSQL语言)。您也可以使用SQL语言(参见我的示例)
Postgres不支持某些类型的数组 - sql_identifier是一个。您可以尝试将转换用于某种基本类型 - 在本例中为文本。
CREATE OR REPLACE FUNCTION names(filter text)
RETURNS text[] AS $$
SELECT array_agg(table_name::text)
FROM information_schema.tables
WHERE table_schema='public'
AND table_type='BASE TABLE' AND table_name LIKE $1;
$$ LANGUAGE sql;
postgres=# select names('foo%');
names
------------
{foo1,foo}
(1 row)