How to generate the “create table” sql statement for an existing table in postgreSQL

后端 未结 19 2051
花落未央
花落未央 2020-11-28 17:49

I have created a table in postgreSQL. I want to look at the SQL statement used to create the table but cannot figure it out.

How do I get the create table

19条回答
  •  悲哀的现实
    2020-11-28 18:19

    Dean Toader Just excellent! I'd modify your code a little, to show all constraints in the table and to make possible to use regexp mask in table name.

    CREATE OR REPLACE FUNCTION public.generate_create_table_statement(p_table_name character varying)
      RETURNS SETOF text AS
    $BODY$
    DECLARE
        v_table_ddl   text;
        column_record record;
        table_rec record;
        constraint_rec record;
        firstrec boolean;
    BEGIN
        FOR table_rec IN
            SELECT c.relname FROM pg_catalog.pg_class c
                LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                    WHERE relkind = 'r'
                    AND relname~ ('^('||p_table_name||')$')
                    AND n.nspname <> 'pg_catalog'
                    AND n.nspname <> 'information_schema'
                    AND n.nspname !~ '^pg_toast'
                    AND pg_catalog.pg_table_is_visible(c.oid)
              ORDER BY c.relname
        LOOP
    
            FOR column_record IN 
                SELECT 
                    b.nspname as schema_name,
                    b.relname as table_name,
                    a.attname as column_name,
                    pg_catalog.format_type(a.atttypid, a.atttypmod) as column_type,
                    CASE WHEN 
                        (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
                         FROM pg_catalog.pg_attrdef d
                         WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) IS NOT NULL THEN
                        'DEFAULT '|| (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
                                      FROM pg_catalog.pg_attrdef d
                                      WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)
                    ELSE
                        ''
                    END as column_default_value,
                    CASE WHEN a.attnotnull = true THEN 
                        'NOT NULL'
                    ELSE
                        'NULL'
                    END as column_not_null,
                    a.attnum as attnum,
                    e.max_attnum as max_attnum
                FROM 
                    pg_catalog.pg_attribute a
                    INNER JOIN 
                     (SELECT c.oid,
                        n.nspname,
                        c.relname
                      FROM pg_catalog.pg_class c
                           LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
                      WHERE c.relname = table_rec.relname
                        AND pg_catalog.pg_table_is_visible(c.oid)
                      ORDER BY 2, 3) b
                    ON a.attrelid = b.oid
                    INNER JOIN 
                     (SELECT 
                          a.attrelid,
                          max(a.attnum) as max_attnum
                      FROM pg_catalog.pg_attribute a
                      WHERE a.attnum > 0 
                        AND NOT a.attisdropped
                      GROUP BY a.attrelid) e
                    ON a.attrelid=e.attrelid
                WHERE a.attnum > 0 
                  AND NOT a.attisdropped
                ORDER BY a.attnum
            LOOP
                IF column_record.attnum = 1 THEN
                    v_table_ddl:='CREATE TABLE '||column_record.schema_name||'.'||column_record.table_name||' (';
                ELSE
                    v_table_ddl:=v_table_ddl||',';
                END IF;
    
                IF column_record.attnum <= column_record.max_attnum THEN
                    v_table_ddl:=v_table_ddl||chr(10)||
                             '    '||column_record.column_name||' '||column_record.column_type||' '||column_record.column_default_value||' '||column_record.column_not_null;
                END IF;
            END LOOP;
    
            firstrec := TRUE;
            FOR constraint_rec IN
                SELECT conname, pg_get_constraintdef(c.oid) as constrainddef 
                    FROM pg_constraint c 
                        WHERE conrelid=(
                            SELECT attrelid FROM pg_attribute
                            WHERE attrelid = (
                                SELECT oid FROM pg_class WHERE relname = table_rec.relname
                            ) AND attname='tableoid'
                        )
            LOOP
                v_table_ddl:=v_table_ddl||','||chr(10);
                v_table_ddl:=v_table_ddl||'CONSTRAINT '||constraint_rec.conname;
                v_table_ddl:=v_table_ddl||chr(10)||'    '||constraint_rec.constrainddef;
                firstrec := FALSE;
            END LOOP;
            v_table_ddl:=v_table_ddl||');';
            RETURN NEXT v_table_ddl;
        END LOOP;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION public.generate_create_table_statement(character varying)
      OWNER TO postgres;
    

    Now you can, for example, make the following query

    SELECT * FROM generate_create_table_statement('.*');
    

    which results like this:

    CREATE TABLE public.answer (                                                                        
         id integer DEFAULT nextval('answer_id_seq'::regclass) NOT NULL,                               
         questionid integer  NOT NULL,                                                                  
         title character varying  NOT NULL,                                                             
         defaultvalue character varying  NULL,                                                          
         valuetype integer  NOT NULL,                                                                   
         isdefault boolean  NULL,                                                                       
         minval double precision  NULL,                                                                 
         maxval double precision  NULL,                                                                 
         followminmax integer DEFAULT 0 NOT NULL,                                                       
    CONSTRAINT answer_pkey                                                                              
         PRIMARY KEY (id),                                                                              
    CONSTRAINT answer_questionid_fkey                                                                  
         FOREIGN KEY (questionid) REFERENCES question(id) ON UPDATE RESTRICT ON DELETE RESTRICT,       
    CONSTRAINT answer_valuetype_fkey                                                                   
         FOREIGN KEY (valuetype) REFERENCES answervaluetype(id) ON UPDATE RESTRICT ON DELETE RESTRICT);
    

    for each user table.

提交回复
热议问题