MySQL スクリプトでは、次のように記述できます。
CREATE TABLE IF NOT EXISTS foo ...;
... 他のもの ...
その後、テーブルを再作成せずにスクリプトを何度も実行できます。
PostgreSQLでこれをどのように行いますか?
MySQL スクリプトでは、次のように記述できます。
CREATE TABLE IF NOT EXISTS foo ...;
... 他のもの ...
その後、テーブルを再作成せずにスクリプトを何度も実行できます。
PostgreSQLでこれをどのように行いますか?
この機能はPostgres 9.1で実装されました。
CREATE TABLE IF NOT EXISTS myschema.mytable (i integer);
古いバージョンの場合、これを回避する機能は次のとおりです。
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$;
電話:
SELECT create_mytable(); -- call as many times as you want.
列schemaname
とtablename
inpg_tables
は大文字と小文字が区別されます。ステートメントで識別子を二重引用符で囲む場合はCREATE TABLE
、まったく同じスペルを使用する必要があります。そうでない場合は、小文字の文字列を使用する必要があります。見る:
pg_tables
実際のテーブルのみが含まれます。識別子は、関連するオブジェクトによって占有されている可能性があります。見る:
この関数を実行するロールがテーブルを作成するために必要な権限を持っていない場合はSECURITY DEFINER
、関数に使用し、必要な権限を持つ別のロールがテーブルを所有するようにすることができます。このバージョンは十分に安全です。
これを試して:
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)
)
既存の回答から、任意のテーブルに再利用できる一般的なソリューションを作成しました。
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);');
クエリ パラメータからテーブル名を抽出する場合は、パラメータを 1 つだけ取るようにさらに単純化できます。また、スキーマを省略しました。
CREATE TABLE IF NOT EXISTS... はありませんが、そのための簡単な手順を次のように書くことができます。
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'
);