将 PGSQL 命令从匿名块内部输出到 SQL 文件

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

我尝试将一些

pgsql
命令(特别是授予)输出到 SQL 文件。

我的代码如下所示:

DO
$$

DECLARE
rec record;

BEGIN

FOR rec in
SELECT 
    pu.usename,
    pr.rolname,
    tp.privilege_type,
    tp.table_name
FROM 
    pg_user pu
JOIN 
    pg_auth_members ON pu.usesysid = pg_auth_members.member
JOIN 
    pg_roles pr ON pr.oid = pg_auth_members.roleid
LEFT JOIN 
    information_schema.table_privileges tp ON pr.rolname = tp.grantee
  
  LOOP
    
    CONTINUE WHEN rec.table_name is null;
    execute 'copy (''grant ' ||rec.privilege_type|| ' on ' ||rec.table_name|| ' to ' ||rec.usename|| ';'') to
    /mydir/backup.csv with csv';

  END LOOP;
    
END
$$;

在我的代码中,我宁愿尝试将代码输出到 CSV 文件中,因为我不知道如何使用 SQL 文件执行此操作,无论如何,如果不可能,我可以重用 CSV 文件。

我收到错误:

ERROR:  syntax error at or near "'grant SELECT on t_table to user2;'"
LINE 1: copy ('grant SELECT on t_table to user2;') to
              ^
QUERY:  copy ('grant SELECT on t_table to user2;') to
    /mydir/backup.csv with csv
CONTEXT:  PL/pgSQL function inline_code_block line 27 at EXECUTE

不幸的是,我不知道我犯了什么语法错误,也不知道在更正语法错误后是否能实现将补助金输出到 CSV 或 SQL 文件的目标。

谁能告诉我语法错误是什么?这个执行命令真的会用我的资助创建一个 CSV 文件吗?我应该先创建一个空文件吗?

postgresql plpgsql
1个回答
0
投票

COPY
不会将字符串写入文件,而是将表的内容(或 SQL 语句的 结果)写入文件。

您可以做的是将您的

GRANT
语句收集在临时表中,然后
COPY
最后将其收集到文件中:

BEGIN
   ...

   CREATE TEMP TABLE tt (x text);

   LOOP
      ...
      INSERT INTO tt VALUES (
         /* prevent SQL injection */
         format(
            'GRANT %s ON %I to %I;',
            rec.privilege_type, rec.table_name, rec.usename
         )
      );
   END LOOP;

   ...
   COPY tt TO '/mydir/backup.csv';
END;

但在您的特殊情况下,您根本不需要循环。您可以编写一个返回

GRANT
语句表的查询,并像

那样使用它
COPY (SELECT ...) TO '/mydir/backup.csv';
© www.soinside.com 2019 - 2024. All rights reserved.