PostgreSQL批量修改函数拥有者的操作

Postgresql如何批量修改函数拥有者,默认创建的函数对象的拥有者为当前创建的用户,如果使用postgres超级管理员创建一个test()的函数,拥有者就是postgres用户。下面讲解下如何批量修改拥有者。

本文演示的Postgresql版本如下:

PostgreSQL 9.6.8

相关视图

要查询Postgresql的函数和函数参数需要使用函数视图和参数视图,分别记录了函数信息和参数列表信息。

视图一: information_schema.routines

视图routines包含当前数据库中所有的函数。只有那些当前用户能够访问(作为拥有者或具有某些特权)的函数才会被显示。需要用到的列如下,完整视图讲解请参考官方文档。

名称 数据类型 备注
specific_schema sql_identifier 包含该函数的模式名
routine_name sql_identifier 该函数的名字(在重载的情况下可能重复)
specific_name sql_identifier 该函数的"专用名"。这是一个在模式中唯一标识该函数的名称,即使该函数真正的名称已经被重载。专用名的格式尚未被定义,它应当仅被用来与指定例程名称的其他实例进行比较。

视图二: information_schema.parameters

视图parameters包含当前数据库中所有函数的参数的有关信息。只有那些当前用户能够访问(作为拥有者或具有某些特权)的函数才会被显示。需要用到的列如下,完整视图讲解请参考官方文档。

名称 数据类型 备注
parameter_name sql_identifier 参数名,如果参数没有名称则为空
udt_name sql_identifier 该参数的数据类型的名字
ordinal_position cardinal_number 该参数在函数参数列表中的顺序位置(从 1 开始计数)
specific_name cardinal_number 该函数的"专用名"。详见第 35.40 节。

注意:可以通过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;

效果:

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • postgresql限制某个用户仅连接某一个数据库的操作

    创建数据库bbb且owner为用户b: postgres9.6@[local]:5432 postgres# create database bbb owner b; CREATE DATABASE Time: 259.099 ms 默认情况下使用用户c也可以连接数据库bbb: postgres9.6@[local]:5432 postgres# \c bbb c You are now connected to database "bbb" as user "c"

  • PostgreSQL 默认权限查看方式

    如何查看PostgreSQL默认权限 当我们对Postgresql的某个用户授予默认权限时, pg_default_acl表存储要被分配给新创建对象的初始权限.你可能通过查询该表获取默认权限,先了解下官方文档的解释: 表 50-17. pg_default_acl的列: 名称 类型 引用 描述 oid oid 行标识符(隐藏属性,必须被显式选择才会显示) defaclrole oid pg_authid.oid 与此项相关的角色的OID defaclnamespace oid pg_namesp

  • PostgreSQL用户、数据库及表的管理、操作与授权方式

    摘要 PostgreSQL的常用命令 1.登录数据库 /* 切换到数据库用户 */ su - postgres /* 登录 */ psql 登录成功显示如下: bash-4.2$ psql psql (9.3.17) Type "help" for help. postgres=> 2.切换数据库 /* 登录指定数据库 */ psql -U user -d dbname /* 列举数据库 */ \l /* 切换数据库 */ \c dbname 3.用户管理 /* 创建用户 */

  • PostgreSQL 实现快速删除一个用户

    背景 在多租户场景或者其他场景下,很多时候需要主动清理一些用户,本文将介绍PostgreSQL 下如何快速删除一个用户(role). 具体方法 一般情况下直接执行 drop role xxx; 就可以把这个用户删除.但是很多时候会因为用户有依赖而报错. 权限依赖 postgres=# create role test with login; CREATE ROLE postgres=# grant all on database postgres to test; GRANT postgres=

  • Postgresql 赋予用户权限和撤销权限的实例

    1.对数据库授权 postgresql 授权某个数据库的权限给wang 账号 使该账号 只能操作指定DB 不能操作其他DB alter user wang set default_transaction_read_only=on; grant all on database test to wang; grant select on all database test to wang; grant select on all tables in schema public to wang; //

  • postgresql 赋权语句 grant的正确使用说明

    grant select on all tables in schema public to username; 此句是有效的复制语句 PG中有schema的概念, 以下的语句就是不行 网上得来终觉浅,错误比较多,还是要自己试试才行. 补充:postgresql关于访问视图需要的权限 某个用户访问一个视图,这个用户需要具备这个视图的schema的usage和这个视图本身的select权限,如果视图的基表来自其他schema,可能还需要其他schema的usage权限(根据postgresql改造

  • PostgreSQL批量修改函数拥有者的操作

    Postgresql如何批量修改函数拥有者,默认创建的函数对象的拥有者为当前创建的用户,如果使用postgres超级管理员创建一个test()的函数,拥有者就是postgres用户.下面讲解下如何批量修改拥有者. 本文演示的Postgresql版本如下: PostgreSQL 9.6.8 相关视图 要查询Postgresql的函数和函数参数需要使用函数视图和参数视图,分别记录了函数信息和参数列表信息. 视图一: information_schema.routines 视图routines包含当前

  • Python实现的批量修改文件后缀名操作示例

    本文实例讲述了Python实现的批量修改文件后缀名操作.分享给大家供大家参考,具体如下: windows和linux下都支持该程序 以下程序可以进行批量修改文件后缀名: #!/usr/bin/env python #coding:utf8 #! python3 #批量修改一个文件下的文件后缀 import sys import os def Rename(): #Path = "F:\\test\\" # windows下的文件目录 Path = input("请输入你需要操

  • 用asp实现的代码批量修改程序,fso相关

    用asp实现的代码批量修改程序,fso相关 是因工作需要做的一个批量修改代码的小东西,拿出来与大家分享 目前可以处理的文件类型:.asp .inc .htm .html 具体类型可自行修改添加 程序实现的功能:将源目录下的文件批量修改后存到目的目录下 用它稍做修改可以实现很多东西噢! 别的不说了,代码里面都写的很清楚了 <% '// +---------------------------------------------------------------------------+ '//

  • go语言实现Elasticsearches批量修改查询及发送MQ操作示例

    目录 update_by_query批量修改 索引添加字段 查询es发送MQ update_by_query批量修改 POST post-v1_1-2021.02,post-v1_1-2021.03,post-v1_1-2021.04/_update_by_query { "query": { "bool": { "must": [ { "term": { "join_field": { "val

  • Mybatis批量修改的操作代码

    1.修改的字段值都是一样的,id不同 <update id="batchUpdate" parameterType="String"> update cbp_order set status=1 where id in <foreach item="id" collection="array" open="(" separator="," close=")&q

  • python文件操作之批量修改文件后缀名的方法

    1.引言 需要把.dat 格式 转化成 .txt格式 2.实现 ##python批量更换后缀名 import os # 列出当前目录下所有的文件 files = os.listdir('.') #print('files',files) for filename in files: portion = os.path.splitext(filename) # 如果后缀是.dat if portion[1] == ".dat": # 重新组合文件名和后缀名 newname = porti

  • Android批量修改文件格式/文件名的神操作分享

    目录 前言 1. 使用 shell 脚本批量修改文件格式/文件名 2. 使用 DocumentFile 批量修改文件格式/文件名 关于 DocumentFile 和 DocumentsContract** 需求扩展 总结 前言 有时候可能会遇到需要批量修改文件格式的需求,但百度了很久都没有找到相关的应用什么的,于是学过两天 Android 的我想自己去弄一个 APP 来实现这个需求. 1. 使用 shell 脚本批量修改文件格式/文件名 第一种方法是我第一次成功的方法,因为 android 本身

  • centos7.6批量增加修改删除虚拟网卡操作介绍

    1 确认内核是否有tun模块 modinfo tun modprobe tun lsmod | grep tun 2 安装tunctl软件 yum install tunctl -y vim /etc/yum.repos.d/nux-misc.repo [nux-misc] name=Nux Misc baseurl=http://li.nux.ro/download/nux/misc/el7/x86_64/ enabled=0 gpgcheck=1 gpgkey=http://li.nux.r

  • Python批量修改文件名实例操作分享

    此处以修改图片文件名为例,将图片复制到新的目录中再修改名称~ 原始文件名如下: 修改后的效果如下: 代码: 实现将one文件夹中的每一个图片复制到two文件夹并修改图片名为按照a.b.c.d递增排序 思路:重命名为新建一个文件将原来文件内容复制过去 import os   def alterFileName(source,target):     print("当前文件夹下有以下几个文件>>>")     file_list=os.listdir(source)  

  • javascript批量修改文件编码格式的方法

    本文实例讲述了javascript批量修改文件编码格式的方法.分享给大家供大家参考.具体如下: 摘要: 最近在制作手册的时候遇到了一个问题'文档乱码',查看文件之后发现文件编码不对,总共100多个文件,如果用编辑器另存为utf8,那就悲催了.所以自己就写了个程序,批量修改文件编码格式. 代码: 复制代码 代码如下: /**  * 修改文件编码格式,例如:GBK转UTF8  * 支持多级目录  * @param {String} [root_path] [需要进行转码的文件路径]  * @para

随机推荐