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 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 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);');
쿼리 매개 변수에서 테이블 이름을 추출하는 경우 하나의 매개 변수 만 사용하면 더 간단해질 수 있습니다. 또한 스키마를 생략했습니다.
답변
이 솔루션은 Erwin Brandstetter의 답변과 다소 유사하지만 SQL 언어 만 사용합니다.
모든 PostgreSQL 설치에 기본적으로 plpqsql 언어가있는 것은 아닙니다. 즉 CREATE LANGUAGE plpgsql
, 함수를 작성하기 전에 호출 한 후 언어를 다시 제거하여 데이터베이스를 이전과 동일한 상태로 두어야합니다 (데이터베이스의 경우에만 해당) plpgsql 언어가 없었습니다). 복잡성이 어떻게 증가하는지보십시오?
스크립트를 로컬로 실행하는 경우 plpgsql을 추가해도 문제가되지 않을 수 있습니다. 그러나 스크립트를 고객에서 스키마를 설정하는 데 사용하는 경우 고객 데이터베이스에 이와 같은 변경 사항을 남기지 않는 것이 좋습니다.
이 솔루션은 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();
답변
존재하지 않으면 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 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'
);