我尝试将一些
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 文件吗?我应该先创建一个空文件吗?
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';