【openGauss/PostgreSQL】openGauss/PostgreSQL批量修改对象owner

【openGauss/PostgreSQL】openGauss/PostgreSQL批量修改对象owner


PostgreSQL批量修改对象owner

创建测试数据

创建数据库

psql -U postgres
create user test password 'test';
create database testdb;
\c testdb
CREATE SCHEMA test AUTHORIZATION postgres;

创建对象

export PGPASSWORD=test
psql -U postgres -d testdb
set searc_path to test;
-- 创建域
create domain phone_type as text constraint phone_check check (VALUE ~ '^\d{11}$');
-- 创建数据类型
CREATE TYPE human_sex AS ENUM ('male', 'female');
CREATE TYPE test_type AS (f1 int, f2 text);
-- 创建序列
create sequence employees_s;
create sequence employees_s1;
-- 创建测试表
create table test_t1(id int);
create table test_t2(id int);
create table test_t3(id int);
create table test_t4(id int);
create table employees
    ( employee_id    int8    primary key
    , first_name     varchar(20)
    , last_name      varchar(25)
    , sex            human_sex
    , email          varchar(25)
    , phone_number   phone_type
    , salary         numeric(8,2)
    , last_update_date timestamp
    , constraint     emp_salary_min check (salary > 0) 
    , constraint     emp_email_uk unique (email)
    ) ;
-- 插入数据
insert into employees values(nextval('employees_s'),'King','Johnn','male','johnn@163.com','15145264084',10000,now());
-- 以下两条应该报错
insert into employees values(nextval('employees_s'),'Job','Lucy','female','lucy@163.com','151452640841',10000,now());
insert into employees values(nextval('employees_s'),'Job','Lucy','females','lucy@163.com','15145264084',10000,now());
-- 创建索引
create index idx_name on employees(first_name,last_name);

视图

-- 普通视图
create view emp as select * from employees;
-- 物化视图
create materialized view emp_v as select * from employees;
refresh materialized view emp_v;

创建触发器

-- 普通触发器
CREATE OR REPLACE FUNCTION update_time_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.last_update_date := CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER update_time_trigger BEFORE UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION update_time_column();

-- 事件触发器
CREATE OR REPLACE FUNCTION DISABLE_DROP_TABLE()
RETURNS event_trigger AS $$
BEGIN
    if tg_tag = 'DROP TABLE'  THEN
        RAISE EXCEPTION 'Command % is disabled.', tg_tag;
    END if;
END;
$$ LANGUAGE plpgsql;

CREATE EVENT TRIGGER DISABLE_DROP_TABLE on ddl_command_start EXECUTE FUNCTION DISABLE_DROP_TABLE();

函数和存储过程

-- 函数
CREATE FUNCTION inc(val integer) RETURNS integer AS $$
BEGIN
  RETURN val + 1;
END;
$$ LANGUAGE PLPGSQL;

CREATE FUNCTION inc(val1 integer,val2 integer) RETURNS integer AS $$
BEGIN
  RETURN val1 + val2;
END;
$$ LANGUAGE PLPGSQL;


-- 存储过程
CREATE OR REPLACE PROCEDURE test_sum(a NUMERIC,b NUMERIC,C NUMERIC)
AS $$
DECLARE
  val int;
BEGIN
  val := a+b+c;
  RAISE NOTICE 'Total is : % !',val;
END;
$$ language plpgsql;

对象信息查询

-- 数据库
select d.datname as "database",
        pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
		d.datacl AS "Access privileges"
FROM pg_catalog.pg_database d where datname = 'testdb';
-- 模式
SELECT n.nspname AS "schema",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner",
  n.nspacl AS "Access privileges"
FROM pg_catalog.pg_namespace n
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
ORDER BY 1;
-- 域
select t2.nspname,t1.typname,t3.usename as owner from pg_type t1
  join pg_namespace t2 on t1.typnamespace=t2.oid
  join pg_user t3 on t1.typowner=t3.usesysid
where t1.typtype ='d'
    and t2.nspname='test';
-- 数据类型
SELECT t.typname AS type_name,
       t.typtype AS type_category,
       t.typowner AS owner_id,
       t.typnamespace::regnamespace AS schema_name,
       t.typacl AS access_privileges
FROM pg_type t
JOIN pg_namespace n ON t.typnamespace = n.oid
LEFT JOIN pg_class c ON c.reltype = t.oid
WHERE t.typtype IN ('c', 'e', 'd', 'b')  -- 仅筛选用户自定义类型
  AND n.nspname NOT IN ('pg_catalog', 'information_schema')  -- 排除系统命名空间
  AND c.relkind IS NULL  -- 排除表、视图和序列
ORDER BY type_name;

-- 对象
select t2.nspname as "schema",
       t1.relname as "object_name",
       case when t1.relkind='r' then '普通表'
            when t1.relkind='i' then '索引'
            when t1.relkind='S' then '序列'
            when t1.relkind='v' then '视图'
            when t1.relkind='m' then '物化视图' end
        as "object_type",
			 t3.usename as "owner",
			 t1.relacl
from pg_class t1,pg_namespace t2,pg_user t3
where t1.relnamespace=t2.oid
and t2.nspname = 'test'
and t1.relowner=t3.usesysid;
-- 约束
select t2.nspname as schema,t3.relname as table,t1.conname,
       case when t1.contype='c' then '检查约束'
            when t1.contype='p' then '主键约束'
            when t1.contype='u' then '唯一约束' end as contype,
       t4.relname as index
from pg_constraint t1 join pg_namespace t2 on t1.connamespace = t2.oid
     join pg_class t3 on t1.conrelid = t3.oid
     left join pg_class t4 on t1.conindid = t4.oid
where t2.nspname = 'test';
-- 普通触发器
select t3.nspname as schema,t2.relname,tgname from pg_trigger t1
  join pg_class t2 on t1.tgrelid=t2.oid
  join pg_namespace t3 on t2.relnamespace=t3.oid
 where t3.nspname = 'test';
-- 事件触发器
select t1.evtname,t2.usename from pg_event_trigger t1
  join pg_user t2 on t1.evtowner = t2.usesysid;
-- 函数/存储过程
select t2.nspname as schema,t1.proname,t3.usename as owner,
       case when t1.prokind='f' then '函数'
            when t1.prokind='p' then '存储过程' end as prokind
from pg_proc t1
  join pg_namespace t2 on t1.pronamespace=t2.oid
  join pg_user t3 on t3.usesysid = t1.proowner
where t2.nspname = 'test';

注意:约束、索引、表上的触发器(普通触发器)是和表关联的,只用修改表的属主即可

批量修改对象owner

针对数据库和模式

alter database testdb owner to test;
alter schema test owner to test;

针对其他对象:

DO $$ << change_owner >>
DECLARE
    new_owner  text := 'test';   -- 变更后的对象owner
    table_names text;
    sequence_names text;
    view_names text;
    mview_names text;
    function_names text;
    procedure_names text;
    domain_names text;
BEGIN
    -- 修改表的owner
    FOR table_names IN SELECT table_name FROM information_schema.tables WHERE table_schema = 'test' AND table_type = 'BASE TABLE' LOOP
        EXECUTE 'ALTER TABLE test.' || table_names || ' OWNER TO '|| new_owner;
    END LOOP;
    -- 修改序列的owner
    FOR sequence_names IN SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = 'test' LOOP
        EXECUTE 'ALTER SEQUENCE test.' || sequence_names || ' OWNER TO '|| new_owner;
    END LOOP;
    -- 修改视图的owner
    FOR view_names IN SELECT table_name FROM information_schema.views WHERE table_schema = 'test' LOOP
        EXECUTE 'ALTER VIEW test.' || view_names || ' OWNER TO '|| new_owner;
    END LOOP;
    -- 修改物化视图的owner
    FOR mview_names IN select matviewname from pg_matviews where schemaname = 'test' LOOP
        EXECUTE 'ALTER MATERIALIZED VIEW test.' || mview_names || ' OWNER TO '|| new_owner;
    END LOOP;
    -- 修改函数的owner
    FOR function_names IN SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'test' AND routine_type = 'FUNCTION' LOOP
        EXECUTE 'ALTER FUNCTION test.' || function_names || '() OWNER TO '|| new_owner;
    END LOOP;
    -- 修改存储过程的owner
    FOR procedure_names IN SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'test' AND routine_type = 'PROCEDURE' LOOP
        EXECUTE 'ALTER PROCEDURE test.' || procedure_names || '() OWNER TO '|| new_owner;
    END LOOP;
    -- 修改域的owner
    FOR domain_names in select t1.typname from pg_type t1 join pg_namespace t2 on t1.typnamespace=t2.oid join pg_user t3 on t1.typowner=t3.usesysidwhere t1.typtype ='d' and t2.nspname='test' loop
        EXECUTE 'ALTER DOMAIN test.' || domain_names || ' OWNER TO '|| new_owner;
END change_owner$$;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tzq@2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值