我使用PostgreSQL并且是一名SQL初学者。我试图从查询中创建一个表,如果我运行:
CREATE TABLE table_name AS
(....query...)
它运作得很好。但是,如果我添加“如果不存在”'并运行:
CREATE TABLE IF NOT EXISTS table_name AS
(....query...)
使用完全相同的查询,我得到:
ERROR: syntax error at or near "as"
有没有办法做到这一点?
答案 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 schema或statistics 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;