Відповіді:
Ця функція була реалізована в Postgres 9.1 :
CREATE TABLE IF NOT EXISTS myschema.mytable (i integer);
Для старих версій тут є функція, що дозволяє обійти її:
CREATE OR REPLACE FUNCTION create_mytable ()
RETURNS void 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$ LANGUAGE plpgsql;
Виклик:
SELECT create_mytable(); -- call as many times as you want.
Примітки:
У стовпцях schemaname
і tablename
в pg_tables
регістрі залежать регістри Якщо ви подвійно цитуєте ідентифікатори у CREATE TABLE
виписці, вам потрібно використовувати точно такий же написання. Якщо ви цього не зробите, вам потрібно використовувати малі рядки. Побачити:
pg_tables
містить лише фактичні таблиці . Ідентифікатор все ще може бути зайнятий пов'язаними об'єктами. Побачити:
Якщо роль, що виконує цю функцію, не має необхідних привілеїв для створення таблиці, яку, можливо, ви хочете використовувати SECURITY DEFINER
для цієї функції та зробити її власником іншої ролі з необхідними привілеями. Ця версія досить безпечна.
CREATE FUNCTION
лише один раз. Це те, SELECT create_mytable();
що ви можете хотіти телефонувати багато разів.
Спробуйте це:
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)
)
IF NOT EXISTS
опцію.
Я створив загальне рішення з існуючих відповідей, яке можна повторно використовувати для будь-якої таблиці:
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);');
Далі можна буде спростити взяти лише один параметр, якщо вилучити назву таблиці з параметра запиту. Також я пропустив схеми.
Це рішення дещо схоже на відповідь Ервіна Брандштеттера, але він використовує лише мову sql.
Не всі установки PostgreSQL за замовчуванням мають мову plpqsql, це означає, що вам доведеться зателефонувати CREATE LANGUAGE plpgsql
перед створенням функції, а потім доведеться знову видалити мову, щоб залишити базу даних у тому ж стані, що був раніше (але тільки якщо база даних не було мови plpgsql для початку). Подивіться, як зростає складність?
Додавання plpgsql може не викликати проблем, якщо ви використовуєте свій сценарій локально, однак, якщо сценарій використовується для налаштування схеми у клієнта, можливо, не бажано залишати такі зміни в базі даних клієнтів.
Це рішення натхнене публікацією Андреаса Шербаума .
-- 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();
СТВОРИТИ ТАБЛИЦІ, ЯКЩО НЕ існує ... Але для цього можна написати просту процедуру, наприклад:
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 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'
);