PostgreSQL的“if not exists”始终会抛出语法错误

4

我正在尝试运行这个代码:

IF NOT EXISTS (
   SELECT FROM information_schema.tables
   WHERE table_schema = 'topgun' AND table_name = 'session'
) 

THEN

CREATE TABLE topgun.session (
  sid varchar NOT NULL COLLATE "default",
  sess json NOT NULL,
  expire timestamp(6) NOT NULL
) WITH (OIDS=FALSE);
ALTER TABLE topgun.session ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;
CREATE INDEX "IDX_session_expire" ON topgun.session ("expire");     

END IF;


我在这里试图创建一个表格、约束和索引(如果表格不存在)。即使我更改空行,也会得到各种语法错误。无论我做什么或在其后添加什么,IF NOT EXISTS 始终会导致错误。就好像 PostgreSQL 根本不认识它一样。即使我从教程中复制代码片段,PostgreSQL 也会出问题。我使用的是 Heroku Postgres,版本号为 12.4。 SELECT 部分本身可以正常工作。 CREATE TABLEALTER TABLECREATE INDEX 行在结构外也能正常工作。错误消息如下:
SQL Error [42601]: ERROR: syntax error at or near "IF"
  Position: 5

1
如果删除了主体(then..body..end if),它是否会抛出错误?如果是,请在问题中_包含_错误消息。如果不是,请重新考虑标题。在考虑并提供SSCCE以及简化SQL之后,_包括_错误消息。 - user2864740
1
已添加两个,抱歉。 - Tamás Polgár
3个回答

2

尝试使用 DO 语句

do $$
begin
IF NOT EXISTS (
   SELECT FROM information_schema.tables
   WHERE table_schema = 'public' AND table_name = 'session'
) 

THEN

CREATE TABLE public.session (
  sid varchar NOT NULL COLLATE "default",
  sess json NOT NULL,
  expire timestamp(6) NOT NULL
) WITH (OIDS=FALSE);
ALTER TABLE public.session ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;
CREATE INDEX "IDX_session_expire" ON public.session ("expire");     

END IF;
end;
$$

演示

最好使用这种方法:

create table if not exists test(Id int)

这似乎有效,但只有在我在“do”和“$$”之间加入换行符并在结束的“$$”后加上分号时才有效。谢谢!不管怎样,有什么区别吗? - Tamás Polgár

1
不需要使用PL/pgSQL,只需在CREATE TABLE部分中使用IF NOT EXISTS选项:
CREATE TABLE IF NOT EXISTS topgun.session (
  sid varchar NOT NULL COLLATE "default",
  sess json NOT NULL,
  expire timestamp(6) NOT NULL,
  CONSTRAINT "session_pkey" PRIMARY KEY ("sid")
);

CREATE INDEX IF NOT EXISTS "IDX_session_expire" ON topgun.session ("expire");     

0

我不得不声明“LANGUAGE plpgsql”以避免错误。

CREATE PROCEDURE init() AS $_$
BEGIN

IF NOT EXISTS (
   SELECT FROM information_schema.tables
   WHERE table_schema = 'topgun' AND table_name = 'session'
) 

THEN

CREATE TABLE topgun.session (
  sid varchar NOT NULL COLLATE "default",
  sess json NOT NULL,
  expire timestamp(6) NOT NULL
) WITH (OIDS=FALSE);
ALTER TABLE topgun.session ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;
CREATE INDEX "IDX_session_expire" ON topgun.session ("expire");     

END IF;
END; $_$ LANGUAGE plpgsql;

CALL init();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接