Programing

존재하지 않는 경우 PostgreSQL 테이블 생성

crosscheck 2020. 6. 24. 07:39
반응형

존재하지 않는 경우 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 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. 

노트:

  • schemanametablename인은 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 (user_id)  
)

기존 답변에서 일반적인 솔루션을 만들었습니다.이 솔루션은 모든 테이블에 재사용 할 수 있습니다.

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);');

쿼리 매개 변수에서 테이블 이름을 추출하면 하나의 매개 변수 만 사용하면 더 간단해질 수 있습니다. 또한 스키마를 생략했습니다. 방법을 알고 있다면 내 솔루션을 자유롭게 확장하십시오-아직 plpgsql에 깊이 빠져 있지 않습니다 (이것이 처음입니다).


존재하지 않으면 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'
  );

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();

참고URL : https://stackoverflow.com/questions/1766046/postgresql-create-table-if-not-exists

반응형