Yanıtlar:
Bu özellik Postgres 9.1'de uygulanmıştır :
CREATE TABLE IF NOT EXISTS myschema.mytable (i integer);
Daha eski sürümler için , etrafta bir işlev vardır:
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;
Aramak:
SELECT create_mytable(); -- call as many times as you want.
Notlar:
Sütunlar schemaname
ve tablename
içinde pg_tables
küçük harfe duyarlıdır. İfadede tanımlayıcıları iki kez tırnak içine CREATE TABLE
alırsanız, aynı yazımı kullanmanız gerekir. Bunu yapmazsanız, küçük harfli dizeler kullanmanız gerekir. Görmek:
pg_tables
yalnızca gerçek tablolar içerir . Tanımlayıcı hala ilgili nesneler tarafından işgal edilmiş olabilir. Görmek:
Rol Eğer yürütme bu işlevi tablo oluşturmak için gerekli ayrıcalıklara sahip değil Kullanmak isteyebileceğiniz SECURITY DEFINER
fonksiyon için ve bunu yapmak olunan gerekli ayrıcalıkları olan başka bir rolde tarafından. Bu sürüm yeterince güvenlidir.
CREATE FUNCTION
yalnızca bir kez çalıştırmalısınız . Bu var SELECT create_mytable();
sen defalarca aramak istediğini biliyoruz.
Bunu dene:
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
seçeneği içeren Postgres 9.1'den önce yayınlanmıştır .
Herhangi bir tablo için yeniden kullanılabilen mevcut cevaplar dışında genel bir çözüm oluşturdum:
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;
Kullanımı:
select create_if_not_exists('my_table', 'CREATE TABLE my_table (id integer NOT NULL);');
Tablo adını sorgu parametresinden çıkarırsa yalnızca bir parametre almak daha da basitleştirilebilir. Ayrıca şemaları da bıraktım.
Bu çözüm Erwin Brandstetter'in cevabına biraz benziyor, ancak sadece sql dilini kullanıyor.
Tüm PostgreSQL kurulumları varsayılan olarak plpqsql diline sahip değildir, bu CREATE LANGUAGE plpgsql
, işlevi oluşturmadan önce aramanız gerekebilir ve daha sonra, veritabanını daha önce olduğu gibi bırakmak için dili tekrar kaldırmanız gerektiği anlamına gelir (ancak yalnızca veritabanı başlamak için plpgsql dili yoktu). Karmaşıklığın nasıl büyüdüğünü görüyor musunuz?
Komut dosyanızı yerel olarak çalıştırıyorsanız plpgsql eklemek sorun yaratmayabilir, ancak komut dosyası bir müşteriye şema ayarlamak için kullanılıyorsa, bunun gibi değişiklikleri müşteri veritabanında bırakmak istenmeyebilir.
Bu çözüm, Andreas Scherbaum'un bir gönderisinden esinlenmiştir .
-- 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();
VARSA, OLUŞTUR TABLOSU yoktur ... ancak bunun için basit bir prosedür yazabilirsiniz, şöyle bir şey:
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;
VARSA, OLUŞTUR TABLOSU yoktur ... ancak bunun için basit bir prosedür yazabilirsiniz, şöyle bir şey:
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'
);