我已经在postgreSQL中创建了一个表。我想查看用于创建表的SQL语句,但无法找出它。
如何通过命令行或SQL语句获得Postgres中现有表的创建表SQL语句?
我已经在postgreSQL中创建了一个表。我想查看用于创建表的SQL语句,但无法找出它。
如何通过命令行或SQL语句获得Postgres中现有表的创建表SQL语句?
当前回答
使用它并在ddl中获得输出。出文件
~/bin/pg_dump -p 30000 -d <db_name> -U <db_user> --schema=<schema_name> -t <table_name> --schema-only >> /tmp/ddl.out
因此这将在路径:/tmp/ DDL .out中生成DDL
其他回答
(注意-此解决方案不适用于PostgreSQL v12+)
我的解决方案是使用psql和-E选项登录postgres db,如下所示:
psql -E -U username -d database
在psql中,运行以下命令查看postgres用来生成的sql 描述表语句:
-- List all tables in the schema (my example schema name is public)
\dt public.*
-- Choose a table name from above
-- For create table of one public.tablename
\d+ public.tablename
基于运行这些描述命令后返回的sql,我能够把它们放在一起 下面是PLPGSQL函数:
CREATE OR REPLACE FUNCTION generate_create_table_statement(p_table_name varchar)
RETURNS text AS
$BODY$
DECLARE
v_table_ddl text;
column_record record;
BEGIN
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 ~ ('^('||p_table_name||')$')
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;
v_table_ddl:=v_table_ddl||');';
RETURN v_table_ddl;
END;
$BODY$
LANGUAGE 'plpgsql' COST 100.0 SECURITY INVOKER;
下面是函数用法:
SELECT generate_create_table_statement('tablename');
下面是drop语句,如果你不想让这个函数永久保存:
DROP FUNCTION generate_create_table_statement(p_table_name varchar);
这是这个老问题的另一个解决方案。多年来,关于这个问题有许多优秀的答案,我的尝试在很大程度上借鉴了它们。
我使用安德烈·列别登科的解决方案作为起点,因为它的输出已经非常接近我的要求。
特点:
following common practice I have moved the foreign key constraints outside the table definition. They are now included as ALTER TABLE statements at the bottom. The reason is that a foreign key can also link to a column of the same table. In that fringe case the constraint can only be created after the table creation is completed. The create table statement would throw an error otherwise. The layout and indenting looks nicer now (at least to my eye) Drop command (commented out) in the header of the definition The solution is offered here as a plpgsql function. The algorithm does however not use any procedural language. The function just wraps one single query that can be used in a pure sql context as well. removed redundant subqueries Identifiers are now quoted if they are identical to reserved postgresql language elements replaced the string concatenation operator || with the appropriate string functions to improve performance, security and readability of the code. Note: the || operator produces NULL if one of the combined strings is NULL. It should only be used when that is the desired behaviour. (check out the usage in the code below for an example)
CREATE OR REPLACE FUNCTION public.wmv_get_table_definition (
p_schema_name character varying,
p_table_name character varying
)
RETURNS SETOF TEXT
AS $BODY$
BEGIN
RETURN query
WITH table_rec AS (
SELECT
c.relname, n.nspname, c.oid
FROM
pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE
relkind = 'r'
AND n.nspname = p_schema_name
AND c.relname LIKE p_table_name
ORDER BY
c.relname
),
col_rec AS (
SELECT
a.attname AS colname,
pg_catalog.format_type(a.atttypid, a.atttypmod) AS coltype,
a.attrelid AS oid,
' DEFAULT ' || (
SELECT
pg_catalog.pg_get_expr(d.adbin, d.adrelid)
FROM
pg_catalog.pg_attrdef d
WHERE
d.adrelid = a.attrelid
AND d.adnum = a.attnum
AND a.atthasdef) AS column_default_value,
CASE WHEN a.attnotnull = TRUE THEN
'NOT NULL'
ELSE
'NULL'
END AS column_not_null,
a.attnum AS attnum
FROM
pg_catalog.pg_attribute a
WHERE
a.attnum > 0
AND NOT a.attisdropped
ORDER BY
a.attnum
),
con_rec AS (
SELECT
conrelid::regclass::text AS relname,
n.nspname,
conname,
pg_get_constraintdef(c.oid) AS condef,
contype,
conrelid AS oid
FROM
pg_constraint c
JOIN pg_namespace n ON n.oid = c.connamespace
),
glue AS (
SELECT
format( E'-- %1$I.%2$I definition\n\n-- Drop table\n\n-- DROP TABLE IF EXISTS %1$I.%2$I\n\nCREATE TABLE %1$I.%2$I (\n', table_rec.nspname, table_rec.relname) AS top,
format( E'\n);\n\n\n-- adempiere.wmv_ghgaudit foreign keys\n\n', table_rec.nspname, table_rec.relname) AS bottom,
oid
FROM
table_rec
),
cols AS (
SELECT
string_agg(format(' %I %s%s %s', colname, coltype, column_default_value, column_not_null), E',\n') AS lines,
oid
FROM
col_rec
GROUP BY
oid
),
constrnt AS (
SELECT
string_agg(format(' CONSTRAINT %s %s', con_rec.conname, con_rec.condef), E',\n') AS lines,
oid
FROM
con_rec
WHERE
contype <> 'f'
GROUP BY
oid
),
frnkey AS (
SELECT
string_agg(format('ALTER TABLE %I.%I ADD CONSTRAINT %s %s', nspname, relname, conname, condef), E';\n') AS lines,
oid
FROM
con_rec
WHERE
contype = 'f'
GROUP BY
oid
)
SELECT
concat(glue.top, cols.lines, E',\n', constrnt.lines, glue.bottom, frnkey.lines, ';')
FROM
glue
JOIN cols ON cols.oid = glue.oid
LEFT JOIN constrnt ON constrnt.oid = glue.oid
LEFT JOIN frnkey ON frnkey.oid = glue.oid;
END;
$BODY$
LANGUAGE plpgsql;
pg_dump -h XXXXXXXXXXX.us-west-1.rds.amazonaws.com -U anyuser -t tablename -s
这是一个有一些编辑的查询,
select 'CREATE TABLE ' || a.attrelid::regclass::text || '(' ||
string_agg(a.attname || ' ' || pg_catalog.format_type(a.atttypid,
a.atttypmod)||
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
||
CASE WHEN a.attnotnull = true THEN
' NOT NULL'
ELSE
'' END,E'\n,') || ');'
FROM pg_catalog.pg_attribute a join pg_class on a.attrelid=pg_class.oid
WHERE a.attrelid::regclass::varchar =
'TABLENAME_with_or_without_schema'
AND a.attnum > 0 AND NOT a.attisdropped and pg_class.relkind='r'
group by a.attrelid;
DataGrip具有与pgAdmin相同的功能。你可以右键点击一个表,你会看到选项自动生成创建表语句。