PostgreSQL: создать таблицу, если не существует AS

Я использую PostgreSQL и являюсь новичком SQL. Я пытаюсь создать таблицу из запроса, и если я запустил:

CREATE TABLE table_name AS
   (....query...)

он работает отлично. Но если я добавлю "if not exists" и запустим:

CREATE TABLE IF NOT EXISTS table_name AS
   (....query...)

используя точно такой же запрос, я получаю:

ERROR: syntax error at or near "as"

Есть ли способ сделать это?

Ответ 1

CREATE TABLE AS считается отдельным оператором от обычного CREATE TABLE, и до тех пор, пока Postgres версия 9.5 (см. Запись в журнале изменений) не поддерживала предложение IF NOT EXISTS. (Обязательно посмотрите правильную версию руководства для той версии, которую вы используете.)

Хотя синтаксис CREATE TABLE... LIKE не такой гибкий, он может быть альтернативой в некоторых ситуациях; вместо того, чтобы брать свою структуру (и содержимое) из SELECT, он копирует структуру другой таблицы или представления.

Следовательно, вы можете написать что-то вроде этого (не проверено); последняя вставка - довольно грязный способ ничего не делать, если таблица уже заполнена:

CREATE OR REPLACE VIEW source_data AS SELECT * FROM foo NATURAL JOIN bar;

CREATE TABLE IF NOT EXISTS snapshot LIKE source_data;

INSERT INTO snapshot
SELECT * FROM source_data
WHERE NOT EXISTS ( SELECT * FROM snapshot );

В качестве альтернативы, если вы хотите отбросить предыдущие данные (например, заброшенную временную таблицу), вы можете условно удалить старую таблицу и безоговорочно создать новую:

DROP TABLE IF EXISTS temp_stuff;

CREATE TEMPORARY TABLE temp_stuff AS SELECT * FROM foo NATURAL JOIN bar;

Ответ 2

Если вы собираетесь написать функцию для этого, оставьте его на таблице системного каталога pg_class, а не на представлениях в или сборщик статистики (который существует только при активации).

CREATE OR REPLACE FUNCTION create_table_qry(_tbl text
                                          , _qry text
                                          , _schema text = NULL)
  RETURNS bool AS
$func$
DECLARE
  _sch text := COALESCE(_schema, current_schema());
BEGIN

IF EXISTS (
   SELECT 1 
   FROM   pg_catalog.pg_class c
   JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
   WHERE  n.nspname = _sch
   AND    c.relname = _tbl
   ) THEN

   RAISE NOTICE 'Name is not free: %.%',_sch, _tbl;
   RETURN  FALSE;
ELSE
EXECUTE format('CREATE TABLE %I.%I AS %s', _sch, _tbl, _qry);

   RAISE NOTICE 'Table created successfully: %.%',_sch, _tbl;
   RETURN  TRUE;
END IF;

END
$func$  LANGUAGE plpgsql;

Функция принимает имя таблицы и строку запроса и необязательно также схему для создания таблицы (по умолчанию используется текущая схема).

Обратите внимание на правильное использование = в заголовке функции и := в теле функции:

Также обратите внимание, как идентификаторы экранируются как идентификаторы. Вы не можете использовать regclass, так как таблица еще не существует:

Ответ 3

Попробуйте это,

create or replace function create_table(tblname text) returns text as
$$ 
BEGIN
$1 = trim($1);
IF not EXISTS (select relname from pg_stat_user_tables where relname =$1) THEN
execute 'create table '||$1||' as select * from tbl'; -- <put your query here>
return ''||$1||' Created Successfully !!';
else
return  ''||$1||' Already Exists !!';
END IF;
END
$$
language plpgsql 

create or replace function create_table_qry(tblname text,qry text) returns text as
$$ 
BEGIN
$1 = trim($1);
IF not EXISTS (select relname from pg_stat_user_tables where relname =$1) THEN
execute 'create table '||$1||' as '||$2||'';
return ''||$1||' Created Successfully !!';
else
return  ''||$1||' Already Exists !!';
END IF;
END
$$
language plpgsql 

Ответ 4

Это просто:

 CREATE TABLE IF NOT EXISTS abc ( sql_id BIGINT(20) NOT NULL
   AUTO_INCREMENT PRIMARY KEY, sender VARCHAR(20) NULL)

Ответ 5

Используйте сделать:

do $$ begin

if not exists (  SELECT 1
   FROM   information_schema.tables 
   WHERE  table_schema = 'schema_name'
   AND    table_name = 'bla ') then

  create table schema_name.bla as select * from blu;
end if;

end $$;