In a MySQL script you can write:
CREATE TABLE IF NOT EXISTS foo ...;
... other stuff ...
and then you can run the script many times without re-creating the table.
How do you do this in PostgreSQL?
In a MySQL script you can write:
CREATE TABLE IF NOT EXISTS foo ...;
... other stuff ...
and then you can run the script many times without re-creating the table.
How do you do this in PostgreSQL?
This feature has been implemented in Postgres 9.1:
CREATE TABLE IF NOT EXISTS myschema.mytable (i integer);
For older versions, here is a function to work around it:
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$;
Call:
SELECT create_mytable(); -- call as many times as you want.
The columns schemaname
and tablename
in pg_tables
are case-sensitive. If you double-quote identifiers in the CREATE TABLE
statement, you need to use the exact same spelling. If you don t, you need to use lower-case strings. See:
pg_tables
only contains actual tables. The identifier may still be occupied by related objects. See:
If the role executing this function does not have the necessary privileges to create the table you might want to use SECURITY DEFINER
for the function and make it owned by another role with the necessary privileges. This version is safe enough.
Try this:
CREATE TABLE IF NOT EXISTS app_user (
username varchar(45) NOT NULL,
password varchar(450) NOT NULL,
enabled integer NOT NULL DEFAULT 1 ,
PRIMARY KEY (username)
)
I created a generic solution out of the existing answers which can be reused for any table:
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;
Usage:
select create_if_not_exists( my_table , CREATE TABLE my_table (id integer NOT NULL); );
It could be simplified further to take just one parameter if one would extract the table name out of the query parameter. Also I left out the schemas.
This solution is somewhat similar to the answer by Erwin Brandstetter, but uses only the sql language.
Not all PostgreSQL installations has the plpqsql language by default, this means you may have to call CREATE LANGUAGE plpgsql
before creating the function, and afterwards have to remove the language again, to leave the database in the same state as it was before (but only if the database did not have the plpgsql language to begin with). See how the complexity grows?
Adding the plpgsql may not be issue if you are running your script locally, however, if the script is used to set up schema at a customer it may not be desirable to leave changes like this in the customers database.
This solution is inspired by a post by Andreas Scherbaum.
-- Function which creates table
CREATE OR REPLACE FUNCTION create_table () RETURNS TEXT AS $$
CREATE TABLE table_name (
i int
);
SELECT extended_recycle_bin created ::TEXT;
$$
LANGUAGE sql ;
-- Test if table exists, and if not create it
SELECT CASE WHEN (SELECT true::BOOLEAN
FROM pg_catalog.pg_tables
WHERE schemaname = public
AND tablename = table_name
) THEN (SELECT success ::TEXT)
ELSE (SELECT create_table())
END;
-- Drop function
DROP FUNCTION create_table();
There is no CREATE TABLE IF NOT EXISTS... but you can write a simple procedure for that, something like:
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
);
There is no CREATE TABLE IF NOT EXISTS... but you can write a simple procedure for that, something like:
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;
我如何将Excel板的数据输入我的Django应用? I m将PosgreSQL数据库作为数据库。
On production our database is a few hundred gigabytes in size. For development and testing, we need to create snapshots of this database that are functionally equivalent, but which are only 10 or 20 ...
I ll take the simplest of the SQL functions as an example: CREATE OR REPLACE FUNCTION skater_name_match(INTEGER,VARCHAR) RETURNS BOOL AS $$ SELECT $1 IN (SELECT skaters_skater.competitor_ptr_id ...
I m 在当地网络上运行几台机器,在Salgresql8.3处撰写一份申请。
I want to join few attributes in select statement as one for example select id, (name + + surname + + age) as info from users this doesn t work, how to do it? I m using postgreSQL.
Hey, I have 2 tables in PostgreSql: 1 - documents: id, title 2 - updates: id, document_id, date and some data: documents: | 1 | Test Title | updates: | 1 | 1 | 2006-01-01 | | 2 | 1 | 2007-01-01 |...
I need to setup my PostgreSQL DB s text encoding to handle non-American English characters that you d find showing up in languages such as German, Spanish, and French. What character encoding should ...
I am using a set of SQL LIKE conditions to go through the alphabet and list all items beginning with the appropriate letter, e.g. to get all books where the title starts with the letter "A": SELECT * ...