PostgreSQL:创建表,如果不存在AS

时间:2014-09-17 17:30:12

标签: sql postgresql create-table

我使用PostgreSQL并且是一名SQL初学者。我试图从查询中创建一个表,如果我运行:

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

它运作得很好。但是,如果我添加“如果不存在”'并运行:

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

使用完全相同的查询,我得到:

ERROR: syntax error at or near "as"

有没有办法做到这一点?

6 个答案:

答案 0 :(得分:16)

CREATE TABLE AS被视为与普通CREATE TABLE的单独声明,而直到Postgres版本9.5 (请参阅changelog entry)不支持{{1}子句。 (请务必查看您所使用版本的手册的正确版本。)

虽然不够灵活,但在某些情况下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 );

答案 1 :(得分:4)

如果您要为此编写函数,请将其基于system catalog table pg_class,而不是基于information schemastatistics collector中的视图(仅在激活后才存在)。

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;

该函数采用表名和查询字符串,还可选择使用模式来创建表(默认为current schema)。

请注意函数标题中=的正确使用和函数体中:=的正确使用:

另请注意标识符如何作为标识符进行转义。您无法使用regclass,因为该表尚不存在,但是:

答案 2 :(得分:0)

试试这个,

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 

答案 3 :(得分:0)

很简单:

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

答案 4 :(得分:0)

使用do:

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 $$;

答案 5 :(得分:0)

用于 REDSHIFT PLPGSQL风格的CTAS(创建表AS)。使用纯PG语法对Erwin Brandstetter喊出根源。

CREATE
OR
REPLACE
PROCEDURE pipeline.sp_create_table_if_not_exists_as (sch VARCHAR, tbl VARCHAR, qry VARCHAR, tbl_attrs VARCHAR)
 AS
    /*
     specifically an exception for CTAS functionality: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_AS.html
    */
$$
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 INFO 'Table already exists: %.%', sch, tbl;
ELSE
    EXECUTE 'CREATE TABLE ' || sch || '.' || tbl || ' ' || tbl_attrs || ' AS ' || qry;
    RAISE INFO 'Table created successfully: %.%, using query: [%], optional attributes: [%]', sch, tbl, qry, tbl_attrs;
END IF;

END;
$$
language plpgsql;