pgsql的语法

GU天乐乐乐! / 2024-09-27 / 原文

DO $$ 
BEGIN 
    IF EXISTS (SELECT 1 FROM pg_catalog.pg_proc WHERE proname = 'sp_FindStringProcOrFunc') THEN
        DROP PROCEDURE sp_FindStringProcOrFunc;
    END IF;
END $$;

-- gzt-20240926
-- 这里是 pgsql数据库:可视化工具 自带 pgadmin 4 其他:navicat、dbeaver等等
-- 查询方式:  call  sp_FindStringProcOrFunc('%张三%') ;
-- 查询字符串在哪些表,那些列存在
-- 快速根据页面上显示的文字字符串定位到数据库的哪些关联表中

CREATE OR REPLACE PROCEDURE sp_FindStringProcOrFunc
(
    old_string VARCHAR
) as
$$
BEGIN 
     
    DECLARE
        tbname varchar(50);
        colname varchar(500);
        sql_stmt text;
        j integer;

    BEGIN
        FOR tbname IN SELECT relname FROM pg_catalog.pg_class WHERE relkind = 'r' and relname in(
            SELECT table_name
            FROM information_schema.tables
            WHERE table_schema NOT LIKE 'pg_%' -- 排除以 'pg_' 开头的模式,这些是系统模式[新建架构的时候是不允许架构名称pg_开头的,所以这里可以大胆排除掉]
                  AND table_schema <> 'information_schema' -- 排除 information_schema 模式
                  AND table_type = 'BASE TABLE' -- 只查询基本表,排除视图
                  and table_catalog =  current_database() -- 只查询当前数据库的
                and table_schema =  current_schema()  --- 只查询当前架构的
        ) LOOP
            FOR colname IN SELECT attname FROM pg_catalog.pg_attribute WHERE attrelid = tbname::regclass AND attnum > 0 AND atttypid IN (
                SELECT oid  FROM pg_catalog.pg_type WHERE 1=1
                -- and typname like '%name%'  or  typname like '%char%' 
                -- or typname like '%text%' or typname like '%str%'  or  typname like '%json%' or typname like '%xml%'
                and typname in('name','text','json','xml','varchar','cstring')
            ) LOOP
                IF colname = old_string THEN
                    RAISE NOTICE '包含有列的表 % 包含有列的表 %', colname, tbname;
                END IF;
                
                sql_stmt := 'SELECT COUNT(1) FROM ' || tbname || ' WHERE ' || colname || ' LIKE ''' || old_string || '''';
                EXECUTE sql_stmt INTO j;
                
                IF j > 0 THEN
                    RAISE NOTICE '包含字串的表名: %,包含字串的列名: %', tbname, colname;
                    
                    sql_stmt := 'SELECT ' || colname || ', * FROM ' || tbname || ' WHERE ' || colname || ' LIKE ''' || old_string || '''';
                    
                    RAISE NOTICE '%', sql_stmt;
 
                END IF;
                 
                 
            END LOOP;
        END LOOP;

    END;
END;
$$
LANGUAGE plpgsql;