Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL "if not exists" always throws syntax error

Tags:

postgresql

I'm trying to run this:

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;

What I'm trying to achieve here is creating a table, a constraint and an index if the table doesn't exist.

I'm getting various syntax errors even when I change empty rows. IF NOT EXISTS always causes an error, no matter what I do or what comes after it. As if PostgreSQL didn't even know it. Even if I copy snippets from tutorials, PostgreSQL freaks out.

I'm using Heroku Postgres, version 12.4.

The SELECT part in itself works. The CREATE TABLE, ALTER TABLE and CREATE INDEX rows also work outside of the structure.

The error message is:

SQL Error [42601]: ERROR: syntax error at or near "IF"
  Position: 5
like image 590
Tamás Polgár Avatar asked Sep 17 '25 12:09

Tamás Polgár


1 Answers

Try with DO statement

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

DEMO

Better you use this approach:

create table if not exists test(Id int)
like image 173
Akhilesh Mishra Avatar answered Sep 20 '25 01:09

Akhilesh Mishra