PostgreSQL创建表(如果不存在)
在MySQL脚本中,您可以编写:PostgreSQL创建表(如果不存在),sql,postgresql,ddl,create-table,database-table,Sql,Postgresql,Ddl,Create Table,Database Table,在MySQL脚本中,您可以编写: CREATE TABLE IF NOT EXISTS foo ...; 。。。其他东西 然后可以多次运行脚本,而无需重新创建表 如何在PostgreSQL中执行此操作?如果不存在创建表,则没有创建表。。。但您可以为此编写一个简单的过程,例如: CREATE OR REPLACE FUNCTION execute(TEXT) RETURNS VOID AS $$ BEGIN EXECUTE $1; END; $$ LANGUAGE plpgsql; SE
CREATE TABLE IF NOT EXISTS foo ...;
。。。其他东西
然后可以多次运行脚本,而无需重新创建表
如何在PostgreSQL中执行此操作?如果不存在创建表,则没有创建表。。。但您可以为此编写一个简单的过程,例如:
CREATE OR REPLACE FUNCTION execute(TEXT) RETURNS VOID AS $$
BEGIN
EXECUTE $1;
END; $$ LANGUAGE plpgsql;
SELECT
execute($$
CREATE TABLE sch.foo
(
i integer
)
$$)
WHERE
NOT exists
(
SELECT *
FROM information_schema.tables
WHERE table_name = 'foo'
AND table_schema = 'sch'
);
CREATE OR REPLACE FUNCTION prc_create_sch_foo_table() RETURNS VOID AS $$
BEGIN
EXECUTE 'CREATE TABLE /* IF NOT EXISTS add for PostgreSQL 9.1+ */ sch.foo (
id serial NOT NULL,
demo_column varchar NOT NULL,
demo_column2 varchar NOT NULL,
CONSTRAINT pk_sch_foo PRIMARY KEY (id));
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column ON sch.foo(demo_column);
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column2 ON sch.foo(demo_column2);'
WHERE NOT EXISTS(SELECT * FROM information_schema.tables
WHERE table_schema = 'sch'
AND table_name = 'foo');
EXCEPTION WHEN null_value_not_allowed THEN
WHEN duplicate_table THEN
WHEN others THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
END; $$ LANGUAGE plpgsql;
这一特点已得到:
对于旧版本,这里提供了一个解决此问题的功能:
CREATE OR REPLACE FUNCTION create_mytable()
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
IF EXISTS (SELECT FROM pg_catalog.pg_tables
WHERE schemaname = 'myschema'
AND tablename = 'mytable') THEN
RAISE NOTICE 'Table myschema.mytable already exists.';
ELSE
CREATE TABLE myschema.mytable (i integer);
END IF;
END
$func$;
电话:
注:
中的pg_tables
和schemaname
列区分大小写。如果在tablename
语句中双引号引用标识符,则需要使用完全相同的拼写。如果没有,则需要使用小写字符串。见:CREATE TABLE
仅包含实际表格。标识符可能仍被相关对象占用。见:pg_表格
- 如果执行此函数的角色没有必要的权限创建您可能希望用于该函数的表,并使其由具有必要权限的其他角色拥有。这个版本足够安全
CREATE OR REPLACE FUNCTION create_if_not_exists (table_name text, create_stmt text)
RETURNS text AS
$_$
BEGIN
IF EXISTS (
SELECT *
FROM pg_catalog.pg_tables
WHERE tablename = table_name
) THEN
RETURN 'TABLE ' || '''' || table_name || '''' || ' ALREADY EXISTS';
ELSE
EXECUTE create_stmt;
RETURN 'CREATED';
END IF;
END;
$_$ LANGUAGE plpgsql;
用法:
select create_if_not_exists('my_table', 'CREATE TABLE my_table (id integer NOT NULL);');
如果要从查询参数中提取表名,则可以进一步简化为只取一个参数。我还遗漏了模式 此解决方案与Erwin Brandstetter的答案有些相似,但只使用sql语言 默认情况下,并非所有PostgreSQL安装都使用plpqsql语言,这意味着您可能必须在创建函数之前调用
CREATE language plpgsql
,然后再次删除该语言,才能使数据库保持与以前相同的状态(但前提是数据库一开始就没有plpgsql语言)
如果在本地运行脚本,则添加plpgsql可能不是问题,但是,如果脚本用于在客户处设置架构,则可能不希望在客户数据库中保留这样的更改
此解决方案的灵感来自
试试这个:
app\u用户不存在时创建表(
用户名varchar(45)不为空,
密码varchar(450)不为空,
已启用的整数不为空默认值“1”,
主键(用户名)
)
如果不存在CREATE TABLE,则不存在该表……但您可以为此编写一个简单的过程,例如:
CREATE OR REPLACE FUNCTION execute(TEXT) RETURNS VOID AS $$
BEGIN
EXECUTE $1;
END; $$ LANGUAGE plpgsql;
SELECT
execute($$
CREATE TABLE sch.foo
(
i integer
)
$$)
WHERE
NOT exists
(
SELECT *
FROM information_schema.tables
WHERE table_name = 'foo'
AND table_schema = 'sch'
);
CREATE OR REPLACE FUNCTION prc_create_sch_foo_table() RETURNS VOID AS $$
BEGIN
EXECUTE 'CREATE TABLE /* IF NOT EXISTS add for PostgreSQL 9.1+ */ sch.foo (
id serial NOT NULL,
demo_column varchar NOT NULL,
demo_column2 varchar NOT NULL,
CONSTRAINT pk_sch_foo PRIMARY KEY (id));
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column ON sch.foo(demo_column);
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column2 ON sch.foo(demo_column2);'
WHERE NOT EXISTS(SELECT * FROM information_schema.tables
WHERE table_schema = 'sch'
AND table_name = 'foo');
EXCEPTION WHEN null_value_not_allowed THEN
WHEN duplicate_table THEN
WHEN others THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
END; $$ LANGUAGE plpgsql;
我被迫使用一个现有的postgres 8.4数据库。这个黑客做了,谢谢你!@Boundless:我看到你的编辑被拒绝为“太小”。我应用了它,因为它不会造成伤害。但是,你应该只执行一次
CREATE函数
。它是SELECT CREATE\u mytable();
您可能想多次调用。布兰德斯特特:我同意您的看法。我遇到的问题是,我不知道函数是否已创建(就像表可能存在或不存在一样)。因此,我想确保在调用函数之前创建了该函数。这实际上是一个更干净的解决方案。应该进行投票。事实上,我担心有多少涉及“函数”的解决方案。@s我注意到其他解决方案是在Postgres 9.1之前发布的,其中包括(如果不存在)
选项。不确定这个答案如何影响但由于@erwin brandstetter answer本身是完整的。@comiventor正确,这一个确实表明了参数的用法是正确的。在看到这一个之前,我没有发现这一点。这确实有点帮助。触发器内部并不总是起作用:错误:关系“foo”已经存在即使在plpgsql可用的情况下,您的解决方案也非常棒。它易于扩展,可以在当时不存在的对象上创建视图和函数。例如,来自外部服务器的表视图。您节省了我的时间!谢谢!
CREATE OR REPLACE FUNCTION prc_create_sch_foo_table() RETURNS VOID AS $$
BEGIN
EXECUTE 'CREATE TABLE /* IF NOT EXISTS add for PostgreSQL 9.1+ */ sch.foo (
id serial NOT NULL,
demo_column varchar NOT NULL,
demo_column2 varchar NOT NULL,
CONSTRAINT pk_sch_foo PRIMARY KEY (id));
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column ON sch.foo(demo_column);
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column2 ON sch.foo(demo_column2);'
WHERE NOT EXISTS(SELECT * FROM information_schema.tables
WHERE table_schema = 'sch'
AND table_name = 'foo');
EXCEPTION WHEN null_value_not_allowed THEN
WHEN duplicate_table THEN
WHEN others THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
END; $$ LANGUAGE plpgsql;