Postgresql如何批量修改函数拥有者,默认创建的函数对象的拥有者为当前创建的用户,如果使用postgres超级管理员创建一个test()的函数,拥有者就是postgres用户。下面讲解下如何批量修改拥有者。
本文演示的Postgresql版本如下:
PostgreSQL 9.6.8
相关视图
要查询Postgresql的函数和函数参数需要使用函数视图和参数视图,分别记录了函数信息和参数列表信息。
视图一: information_schema.routines
视图routines包含当前数据库中所有的函数。只有那些当前用户能够访问(作为拥有者或具有某些特权)的函数才会被显示。需要用到的列如下,完整视图讲解请参考官方文档。
视图二: information_schema.parameters
视图parameters包含当前数据库中所有函数的参数的有关信息。只有那些当前用户能够访问(作为拥有者或具有某些特权)的函数才会被显示。需要用到的列如下,完整视图讲解请参考官方文档。
注意:可以通过routines. specific_name 和 parameters.specific_name字段关联查询。
单个修改
如果需要修改的函数只有一个,请执行如下SQL语句即可:
如果需要修改的函数只有一个,请执行如下SQL语句即可:
// 无参数函数 ALTER FUNCTION "abc"."test"() OWNER TO "dbadmin"; //带参数函数 ALTER FUNCTION "abc"."test3"(p1 varchar, p2 varchar) OWNER TO "dbadmin";
批量修改
首先可以查询当前模式下函数的所有者分别是哪个用户,使用下面SQL来查询:
SELECT n.nspname as "Schema", p.proname as "Name", pg_catalog.pg_get_function_result(p.oid) as "Result data type", pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types", pg_catalog.pg_get_userbyid(p.proowner) as "Owner" FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang WHERE pg_catalog.pg_function_is_visible(p.oid) AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' ORDER BY 1, 2;
当前显示模式“abc”有2个无参函数和1个带参函数,拥有者都是postgres超级用户。
然后根据上面讲的两个视图: routines 和 parameters关联查询出模式下的所有函数和参数(目的是为了拼接SQL语句),参考如下:
SELECT "routines".specific_schema, "routines".routine_name, COALESCE("parameters".parameter_name, '') AS parameter_name, -- COALESCE返回参数中的第一个非null的值 COALESCE("parameters".udt_name, '') AS udt_name, COALESCE("parameters".parameter_name, '') || ' ' || COALESCE("parameters".udt_name, '') AS params, "parameters".ordinal_position FROM "information_schema"."routines" LEFT JOIN "information_schema"."parameters" ON "routines".specific_name="parameters".specific_name WHERE "routines".specific_schema='abc' ORDER BY 1,2,6;
这里我们再使用聚合函数: string_agg 把字段 params所有行连接成字符串,并用逗号分隔符分隔。
WITH tmp AS (SELECT "routines".specific_schema, "routines".routine_name, COALESCE("parameters".parameter_name, '') AS parameter_name, -- COALESCE返回参数中的第一个非null的值 COALESCE("parameters".udt_name, '') AS udt_name, COALESCE("parameters".parameter_name, '') || ' ' || COALESCE("parameters".udt_name, '') AS params, "parameters".ordinal_position FROM "information_schema"."routines" LEFT JOIN "information_schema"."parameters" ON "routines".specific_name="parameters".specific_name WHERE "routines".specific_schema='abc' ORDER BY 1,2,6) SELECT specific_schema, routine_name, string_agg(params, ',') AS params, '"'||specific_schema||'"."'||routine_name||'"('||string_agg(params, ',')||')' AS fname FROM tmp GROUP BY specific_schema, routine_name;
最后使用一个Postgres执行代码片段完成批量修改,完整SQL如下:
DO $$ DECLARE r record; BEGIN FOR r IN WITH tmp AS (SELECT "routines".specific_schema, "routines".routine_name, COALESCE("parameters".parameter_name, '') AS parameter_name, -- COALESCE返回参数中的第一个非null的值 COALESCE("parameters".udt_name, '') AS udt_name, COALESCE("parameters".parameter_name, '') || ' ' || COALESCE("parameters".udt_name, '') AS params, "parameters".ordinal_position FROM "information_schema"."routines" LEFT JOIN "information_schema"."parameters" ON "routines".specific_name="parameters".specific_name WHERE "routines".specific_schema='abc' ORDER BY 1,2,6) SELECT '"'||specific_schema||'"."'||routine_name||'"('||string_agg(params, ',')||')' AS fname FROM tmp GROUP BY specific_schema, routine_name LOOP EXECUTE 'ALTER FUNCTION '|| r.fname||' OWNER TO "dbadmin" '; END LOOP; END $$;
可以看到模式“abc”的Owner已经全部改为dbadmin这个账号了。
上次批量修改函数可能存在部分特殊场景会报错, 会把“参数类型” + “返回类型” 拼接在一起
改进方法:我们通过pg_catalog目录来实现批量修改,参考代码如下:
DO $$ DECLARE r record; BEGIN FOR r IN WITH tmp AS ( SELECT n.nspname as "Schema", p.proname as "Name", pg_catalog.pg_get_function_result(p.oid) as "Result data type", pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types", CASE WHEN p.proisagg THEN 'agg' WHEN p.proiswindow THEN 'window' WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger' ELSE 'normal' END as "Type" FROM pg_catalog.pg_proc p LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname = 'etl' ORDER BY 1, 2, 4 ) SELECT '"' || "Schema" || '"' || '.' || '"' || "Name" || '"' || '(' || "Argument data types" ||')' AS fname FROM tmp LOOP EXECUTE 'ALTER FUNCTION '|| r.fname||' OWNER TO "postgres" '; END LOOP; END $$;
补充:PostgreSQL更改Owner所有者
网上一个大神写的
SELECT ‘alter table ' || nsp.nspname || ‘.' || cls.relname || ' owner to usr_zhudong;' || chr ( 13 ) FROM pg_catalog.pg_class cls, pg_catalog.pg_namespace nsp WHERE nsp.nspname IN ( ‘public' ) AND cls.relnamespace = nsp.oid AND cls.relkind = ‘r' ORDER BY nsp.nspname, cls.relname;
我来做一个改版
SELECT 'alter table ' || nsp.nspname || '.' || cls.relname || ' owner to test2;' || chr ( 13 ) FROM pg_catalog.pg_class cls, pg_catalog.pg_namespace nsp WHERE nsp.nspname IN ( 'public' ) AND cls.relnamespace = nsp.oid AND cls.relkind = 'r' ORDER BY nsp.nspname, cls.relname; SELECT 'alter table "' || nsp.nspname || '"."' || cls.relname || '" owner to user01;' || chr ( 13 ) FROM pg_catalog.pg_class cls, pg_catalog.pg_namespace nsp WHERE nsp.nspname IN ( 'public' ) AND cls.relnamespace = nsp.oid AND cls.relkind = 'r' ORDER BY nsp.nspname, cls.relname;
效果:
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]