首页 > 数据库 >PostgreSQL 通过SQL获取建表语句实现 show create table

PostgreSQL 通过SQL获取建表语句实现 show create table

时间:2023-09-11 11:46:06浏览次数:38  
标签:PostgreSQL name show create oid record pg ddl table

有scheme参数

创建函数

CREATE OR REPLACE FUNCTION show_create_table(
    in_schema_name varchar,
    in_table_name varchar
)
    RETURNS text
    LANGUAGE plpgsql VOLATILE
AS
$$
DECLARE
    -- the ddl we're building
    v_table_ddl text;

    -- data about the target table
    v_table_oid int;

    v_table_type char;
    v_partition_key varchar;
    v_table_comment varchar;

    -- records for looping
    v_column_record record;
    v_constraint_record record;
    v_index_record record;
    v_column_comment_record record;
    v_index_comment_record record;
    v_constraint_comment_record record;
BEGIN
    -- grab the oid of the table; https://www.postgresql.org/docs/8.3/catalog-pg-class.html
    SELECT c.oid, c.relkind INTO v_table_oid, v_table_type
    FROM pg_catalog.pg_class c
             LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE c.relkind in ('r', 'p')
      AND c.relname = in_table_name -- the table name
      AND n.nspname = in_schema_name; -- the schema

    -- throw an error if table was not found
    IF (v_table_oid IS NULL) THEN
        RAISE EXCEPTION 'table does not exist';
    END IF;

    -- start the create definition
    v_table_ddl := 'CREATE TABLE "' || in_table_name || '" (' || E'\n';

    -- define all of the columns in the table; https://stackoverflow.com/a/8153081/3068233
    FOR v_column_record IN
        SELECT
            c.column_name,
            c.data_type,
            c.character_maximum_length,
            c.is_nullable,
            c.column_default
        FROM information_schema.columns c
        WHERE (table_schema, table_name) = (in_schema_name, in_table_name)
        ORDER BY ordinal_position
        LOOP
            v_table_ddl := v_table_ddl || '  ' -- note: two char spacer to start, to indent the column
                               || '"' || v_column_record.column_name || '" '
                               || v_column_record.data_type || CASE WHEN v_column_record.character_maximum_length IS NOT NULL THEN ('(' || v_column_record.character_maximum_length || ')') ELSE '' END || ' '
                               || CASE WHEN v_column_record.is_nullable = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
                               || CASE WHEN v_column_record.column_default IS NOT null THEN (' DEFAULT ' || v_column_record.column_default) ELSE '' END
                               || ',' || E'\n';
        END LOOP;

    -- define all the constraints in the; https://www.postgresql.org/docs/9.1/catalog-pg-constraint.html && https://dba.stackexchange.com/a/214877/75296
    FOR v_constraint_record IN
        SELECT
            con.conname as constraint_name,
            con.contype as constraint_type,
            CASE
                WHEN con.contype = 'p' THEN 1 -- primary key constraint
                WHEN con.contype = 'u' THEN 2 -- unique constraint
                WHEN con.contype = 'f' THEN 3 -- foreign key constraint
                WHEN con.contype = 'c' THEN 4
                ELSE 5
                END as type_rank,
            pg_get_constraintdef(con.oid) as constraint_definition
        FROM pg_catalog.pg_constraint con
                 JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
                 JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
        WHERE nsp.nspname = in_schema_name
          AND rel.relname = in_table_name
        ORDER BY type_rank
        LOOP
            IF v_constraint_record.constraint_type = 'p' THEN
                v_table_ddl := v_table_ddl || '  '
                                   || v_constraint_record.constraint_definition
                                   || ',' || E'\n';
            ELSE
                v_table_ddl := v_table_ddl || '  ' -- note: two char spacer to start, to indent the column
                                   || 'CONSTRAINT' || ' '
                                   || '"' || v_constraint_record.constraint_name || '" '
                                   || v_constraint_record.constraint_definition
                                   || ',' || E'\n';
            END IF;
        END LOOP;

    -- drop the last comma before ending the create statement
    v_table_ddl = substr(v_table_ddl, 0, length(v_table_ddl) - 1) || E'\n';

    -- end the create definition
    v_table_ddl := v_table_ddl || ')';

    IF v_table_type = 'p' THEN
        SELECT pg_get_partkeydef(v_table_oid) INTO v_partition_key;
        IF v_partition_key IS NOT NULL THEN
            v_table_ddl := v_table_ddl || ' PARTITION BY ' || v_partition_key;
        END IF;
    END IF;

    v_table_ddl := v_table_ddl || ';' || E'\n';

    -- suffix create statement with all of the indexes on the table
    FOR v_index_record IN
        SELECT regexp_replace(indexdef, ' "?' || schemaname || '"?\.', ' ') AS indexdef
        FROM pg_catalog.pg_indexes
        WHERE (schemaname, tablename) = (in_schema_name, in_table_name)
          AND indexname NOT IN (
            select con.conname
            FROM pg_catalog.pg_constraint con
                     JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
                     JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
            WHERE nsp.nspname = in_schema_name
              AND rel.relname = in_table_name
        )
        LOOP
            v_table_ddl := v_table_ddl
                               || v_index_record.indexdef
                               || ';' || E'\n';
        END LOOP;

    -- comment on table
    SELECT description INTO v_table_comment
    FROM pg_catalog.pg_description
    WHERE objoid = v_table_oid AND objsubid = 0;

    IF v_table_comment IS NOT NULL THEN
        v_table_ddl := v_table_ddl || 'COMMENT ON TABLE "' || in_table_name || '" IS ''' || replace(v_table_comment, '''', '''''') || ''';' || E'\n';
    END IF;

    -- comment on column
    FOR v_column_comment_record IN
        SELECT col.column_name, d.description
        FROM information_schema.columns col
                 JOIN pg_catalog.pg_class c ON c.relname = col.table_name
                 JOIN pg_catalog.pg_namespace nsp ON nsp.oid = c.relnamespace AND col.table_schema = nsp.nspname
                 JOIN pg_catalog.pg_description d ON d.objoid = c.oid AND d.objsubid = col.ordinal_position
        WHERE c.oid = v_table_oid
        ORDER BY col.ordinal_position
        LOOP
            v_table_ddl := v_table_ddl || 'COMMENT ON COLUMN "' || in_table_name || '"."'
                               || v_column_comment_record.column_name || '" IS '''
                               || replace(v_column_comment_record.description, '''', '''''') || ''';' || E'\n';
        END LOOP;

    -- comment on index
    FOR v_index_comment_record IN
        SELECT c.relname, d.description
        FROM pg_catalog.pg_index idx
                 JOIN pg_catalog.pg_class c ON idx.indexrelid = c.oid
                 JOIN pg_catalog.pg_description d ON idx.indexrelid = d.objoid
        WHERE idx.indrelid = v_table_oid
        LOOP
            v_table_ddl := v_table_ddl || 'COMMENT ON INDEX "'
                               || v_index_comment_record.relname || '" IS '''
                               || replace(v_index_comment_record.description, '''', '''''') || ''';' || E'\n';
        END LOOP;

    -- comment on constraint
    FOR v_constraint_comment_record IN
        SELECT
            con.conname,
            pg_description.description
        FROM pg_catalog.pg_constraint con
                 JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
                 JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
                 JOIN pg_catalog.pg_description ON pg_description.objoid = con.oid
        WHERE rel.oid = v_table_oid
        LOOP
            v_table_ddl := v_table_ddl || 'COMMENT ON CONSTRAINT "'
                               || v_constraint_comment_record.conname || '" ON "' || in_table_name || '" IS '''
                               || replace(v_constraint_comment_record.description, '''', '''''') || ''';' || E'\n';
        END LOOP;

    -- return the ddl
    RETURN v_table_ddl;
END
$$;

使用

select show_create_table('public', 't1');

输出

CREATE TABLE "t1" (
  "id" integer NOT NULL,
  "name" character varying(255) NULL,
  "create_time" timestamp without time zone NOT NULL DEFAULT now(),
  "user_id" integer NULL,
  CONSTRAINT "t1_pk" UNIQUE (name),
  CONSTRAINT "t1_tuser_id_fk" FOREIGN KEY (user_id) REFERENCES t_user(id)
);
CREATE INDEX t1_create_time_index ON t1 USING btree (create_time);
COMMENT ON TABLE "t1" IS '测试表';
COMMENT ON COLUMN "t1"."name" IS '名称';
COMMENT ON INDEX "t1_create_time_index" IS '创建时间索引';
COMMENT ON CONSTRAINT "t1_t_user_id_fk" ON "t1" IS '用户外键';

无scheme参数,只查当前连接的scheme

创建函数

CREATE OR REPLACE FUNCTION show_create_table(
    in_table_name varchar
)
    RETURNS text
    LANGUAGE plpgsql VOLATILE
AS
$$
DECLARE
    -- the ddl we're building
    v_table_ddl text;

    -- data about the target table
    v_table_oid int;

    v_table_type char;
    v_partition_key varchar;
    v_namespace varchar;
    v_table_comment varchar;

    -- records for looping
    v_column_record record;
    v_constraint_record record;
    v_index_record record;
    v_column_comment_record record;
    v_index_comment_record record;
    v_constraint_comment_record record;
BEGIN
    -- grab the oid of the table; https://www.postgresql.org/docs/8.3/catalog-pg-class.html
    SELECT c.oid, c.relkind, n.nspname INTO v_table_oid, v_table_type, v_namespace
    FROM pg_catalog.pg_class c
             LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE c.relkind in ('r', 'p')
      AND c.relname = in_table_name -- the table name
      AND pg_catalog.pg_table_is_visible(c.oid); -- the schema

    -- throw an error if table was not found
    IF (v_table_oid IS NULL) THEN
        RAISE EXCEPTION 'table does not exist';
    END IF;

    -- start the create definition
    v_table_ddl := 'CREATE TABLE "' || in_table_name || '" (' || E'\n';

    -- define all of the columns in the table; https://stackoverflow.com/a/8153081/3068233
    FOR v_column_record IN
        SELECT
            c.column_name,
            c.data_type,
            c.character_maximum_length,
            c.is_nullable,
            c.column_default
        FROM information_schema.columns c
        WHERE table_name = in_table_name and table_schema = v_namespace
        ORDER BY ordinal_position
        LOOP
            v_table_ddl := v_table_ddl || '  ' -- note: two char spacer to start, to indent the column
                               || '"' || v_column_record.column_name || '" '
                               || v_column_record.data_type || CASE WHEN v_column_record.character_maximum_length IS NOT NULL THEN ('(' || v_column_record.character_maximum_length || ')') ELSE '' END || ' '
                               || CASE WHEN v_column_record.is_nullable = 'NO' THEN 'NOT NULL' ELSE 'NULL' END
                               || CASE WHEN v_column_record.column_default IS NOT null THEN (' DEFAULT ' || v_column_record.column_default) ELSE '' END
                               || ',' || E'\n';
        END LOOP;

    -- define all the constraints in the; https://www.postgresql.org/docs/9.1/catalog-pg-constraint.html && https://dba.stackexchange.com/a/214877/75296
    FOR v_constraint_record IN
        SELECT
            con.conname as constraint_name,
            con.contype as constraint_type,
            CASE
                WHEN con.contype = 'p' THEN 1 -- primary key constraint
                WHEN con.contype = 'u' THEN 2 -- unique constraint
                WHEN con.contype = 'f' THEN 3 -- foreign key constraint
                WHEN con.contype = 'c' THEN 4
                ELSE 5
                END as type_rank,
            pg_get_constraintdef(con.oid) as constraint_definition
        FROM pg_catalog.pg_constraint con
                 JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
                 JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
        WHERE rel.relname = in_table_name
          AND pg_catalog.pg_table_is_visible(rel.oid)
        ORDER BY type_rank
        LOOP
            IF v_constraint_record.constraint_type = 'p' THEN
                v_table_ddl := v_table_ddl || '  '
                                   || v_constraint_record.constraint_definition
                                   || ',' || E'\n';
            ELSE
                v_table_ddl := v_table_ddl || '  ' -- note: two char spacer to start, to indent the column
                                   || 'CONSTRAINT' || ' '
                                   || '"' || v_constraint_record.constraint_name || '" '
                                   || v_constraint_record.constraint_definition
                                   || ',' || E'\n';
            END IF;
        END LOOP;

    -- drop the last comma before ending the create statement
    v_table_ddl = substr(v_table_ddl, 0, length(v_table_ddl) - 1) || E'\n';

    -- end the create definition
    v_table_ddl := v_table_ddl || ')';

    IF v_table_type = 'p' THEN
        SELECT pg_get_partkeydef(v_table_oid) INTO v_partition_key;
        IF v_partition_key IS NOT NULL THEN
            v_table_ddl := v_table_ddl || ' PARTITION BY ' || v_partition_key;
        END IF;
    END IF;

    v_table_ddl := v_table_ddl || ';' || E'\n';

    -- suffix create statement with all of the indexes on the table
    FOR v_index_record IN
        SELECT regexp_replace(idx.indexdef, ' "?' || idx.schemaname || '"?\.', ' ') AS indexdef
        FROM pg_indexes idx
                 JOIN (
            SELECT ns.nspname, cls.relname
            FROM pg_catalog.pg_class cls
                     LEFT JOIN pg_catalog.pg_namespace ns ON ns.oid = cls.relnamespace
            WHERE pg_catalog.pg_table_is_visible(cls.oid)
        ) t ON idx.schemaname = t.nspname AND idx.tablename = t.relname
        WHERE idx.tablename = in_table_name
          AND idx.indexname NOT IN (
            select con.conname
            FROM pg_catalog.pg_constraint con
                     JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
                     JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
            WHERE rel.relname = in_table_name
              AND pg_catalog.pg_table_is_visible(rel.oid)
        )
        LOOP
            v_table_ddl := v_table_ddl
                               || v_index_record.indexdef
                               || ';' || E'\n';
        END LOOP;

    -- comment on table
    SELECT description INTO v_table_comment
    FROM pg_catalog.pg_description
    WHERE objoid = v_table_oid AND objsubid = 0;

    IF v_table_comment IS NOT NULL THEN
        v_table_ddl := v_table_ddl || 'COMMENT ON TABLE "' || in_table_name || '" IS ''' || replace(v_table_comment, '''', '''''') || ''';' || E'\n';
    END IF;

    -- comment on column
    FOR v_column_comment_record IN
        SELECT col.column_name, d.description
        FROM information_schema.columns col
                 JOIN pg_catalog.pg_class c ON c.relname = col.table_name
                 JOIN pg_catalog.pg_namespace nsp ON nsp.oid = c.relnamespace AND col.table_schema = nsp.nspname
                 JOIN pg_catalog.pg_description d ON d.objoid = c.oid AND d.objsubid = col.ordinal_position
        WHERE c.oid = v_table_oid
        ORDER BY col.ordinal_position
        LOOP
            v_table_ddl := v_table_ddl || 'COMMENT ON COLUMN "' || in_table_name || '"."'
                               || v_column_comment_record.column_name || '" IS '''
                               || replace(v_column_comment_record.description, '''', '''''') || ''';' || E'\n';
        END LOOP;

    -- comment on index
    FOR v_index_comment_record IN
        SELECT c.relname, d.description
        FROM pg_catalog.pg_index idx
                 JOIN pg_catalog.pg_class c ON idx.indexrelid = c.oid
                 JOIN pg_catalog.pg_description d ON idx.indexrelid = d.objoid
        WHERE idx.indrelid = v_table_oid
        LOOP
            v_table_ddl := v_table_ddl || 'COMMENT ON INDEX "'
                               || v_index_comment_record.relname || '" IS '''
                               || replace(v_index_comment_record.description, '''', '''''') || ''';' || E'\n';
        END LOOP;

    -- comment on constraint
    FOR v_constraint_comment_record IN
        SELECT
            con.conname,
            pg_description.description
        FROM pg_catalog.pg_constraint con
                 JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
                 JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
                 JOIN pg_catalog.pg_description ON pg_description.objoid = con.oid
        WHERE rel.oid = v_table_oid
        LOOP
            v_table_ddl := v_table_ddl || 'COMMENT ON CONSTRAINT "'
                               || v_constraint_comment_record.conname || '" ON "' || in_table_name || '" IS '''
                               || replace(v_constraint_comment_record.description, '''', '''''') || ''';' || E'\n';
        END LOOP;

    -- return the ddl
    RETURN v_table_ddl;
END
$$;

使用

select show_create_table('t1');

输出

CREATE TABLE "t1" (
  "id" integer NOT NULL,
  "name" character varying(255) NULL,
  "create_time" timestamp without time zone NOT NULL DEFAULT now(),
  "user_id" integer NULL,
  CONSTRAINT "t1_pk" UNIQUE (name),
  CONSTRAINT "t1_t_user_id_fk" FOREIGN KEY (user_id) REFERENCES t_user(id)
);
CREATE INDEX t1_create_time_index ON t1 USING btree (create_time);
COMMENT ON TABLE "t1" IS '测试表';
COMMENT ON COLUMN "t1"."name" IS '名称';
COMMENT ON INDEX "t1_create_time_index" IS '创建时间索引';
COMMENT ON CONSTRAINT "t1_t_user_id_fk" ON "t1" IS '用户外键';

参考

标签:PostgreSQL,name,show,create,oid,record,pg,ddl,table
From: https://www.cnblogs.com/ffpy/p/17693116.html

相关文章

  • PostgreSQL数据库从入门到精通系列之五:深入理解lsn_proc、lsn_commit、lsn、txId、ts_
    PostgreSQL数据库从入门到精通系列之五:深入理解lsn_proc、lsn_commit、lsn、txId、ts_usec一、深入理解lsn_proc二、深入理解lsn_commit三、深入理解lsn四、深入理解txId五、深入理解ts_usec一、深入理解lsn_proc在PostgreSQL中,lsn_proc是一个内置函数,用于将逻辑日志位置(LSN)转换......
  • PostgreSQL数据库从入门到精通系列之六:深入理解逻辑复制槽,创建逻辑复制槽,删除逻辑复制
    PostgreSQL数据库从入门到精通系列之六:深入理解逻辑复制槽,创建逻辑复制槽,删除逻辑复制槽一、逻辑复制槽二、创建逻辑复制槽三、删除逻辑复制槽一、逻辑复制槽在PostgreSQL中,逻辑复制槽是一种用于实现逻辑复制的功能。逻辑复制槽允许将源数据库的更改流式传输到目标数据库,并使目标......
  • postgresql数据库安装日志解析插件wal2json
    postgresql数据库安装日志解析插件wal2json一、编译安装wal2json插件cdwal2jsonexportPATH=/data/home/fei.yang4/moudle/postgresql/bin:$PATHmakemakeinstall二、直接导入wal2json插件查看pg进程确定pgsql库和配置文件存放目录ps-ef|greppostgresqlubuntu24975248......
  • Hive表分区查询show partitions tablename
    Hive表分区查询showpartitionstablenameSparkSql:%sqlshowpartitionsgrainfo;......
  • Vue.js 官方脚手架 create-vue 是怎么实现的?
    Vue.js官方脚手架create-vue是怎么实现的?摘要本文共分为四个部分,系统解析了vue.js官方脚手架create-vue的实现细节。第一部分主要是一些准备工作,如源码下载、项目组织结构分析、依赖分析、功能点分析等;第二部分分析了create-vue脚手架是如何执行的,执行文件的生成细节......
  • kubectl 命令详解(十七):create configmap
    一、命令作用根据配置文件、目录或指定的literal-value创建configmap。configmap用来保存一个或多个key/value信息。当基于配置文件创建configmap时,key将默认为文件的基础名称,value默认为文件文本内容。如果基本名称的key无效,则可以指定另一个key。当基于目录创建config......
  • 用matplotlib迭代画图,在plt.show()执行后代码暂停
    https://tieba.baidu.com/p/4778495824幸好刚刚找到答案了,对于题主来说可能是帮不上忙了,但是对于碰巧搜到这里的同萌们可能会方便很多,最简实现如下(Python3.6.2):importmatplotlib.pyplotaspltimportnumpyasnpplt.ion()#开启interactivemodex=np.linspace(0,50,1000)pl......
  • mysql create procedure with in parameters ,call procedure
    //createprocedurestatementdelimiter$$usedb$$dropprocedureifexistsinsertIntoT1Table;createprocedureinsertIntoT1Table(innumint)begindeclareiintdefault1;while(i<num)doinsertintot1(name,abstract,author,content,summary)values(uui......
  • python3 postgreSQL 依赖问题
    unabletoexecute'gcc':NosuchfileordirectoryItappearsyouaremissingsomeprerequisitetobuildthepackagefromsource.Youmayinstallabinarypackagebyinstalling'psycopg2-binary'fromPyPI.Ifyouwantto......
  • DBeaver执行sql脚本报错:CreateProcess error=193, %1 不是有效的 Win32 应用程序。
    DBeaver执行sql脚本报错:CreateProcesserror=193,%1不是有效的Win32应用程序。如图:  定位发现DBeaver默认安装的mysql.exe大小为0字节!解决方案,重新给DBeaver指定有效的mysql安装的bin目录下mysql.exe即可:选中当前的mysql连接,右键:编辑连接-主要-本地客户端-浏览......