Re: Create table if not exists ... how ??

Lists: pgsql-general
From: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Create table if not exists ... how ??
Date: 2010-07-19 16:33:39
Message-ID: AANLkTikaCWrB_Dd-s4adMisqd-YR3wMudBi3yLYLcE1V@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I can't figure out the correct syntax...

I have this, but it just keeps complaining about the IF

IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
table_name = 'post_codes')

THEN

CREATE TABLE post_codes
(
area character varying(10) NOT NULL,
district character varying(10) NOT NULL,
sector character varying(10) NOT NULL,
CONSTRAINT post_codes_pkey PRIMARY KEY (area, district, sector)
)
WITH (
OIDS=FALSE
);
ALTER TABLE post_codes OWNER TO postgres;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - -

ERROR: syntax error at or near "IF"
LINE 1: IF NOT EXISTS (SELECT table_name FROM information_schema.tab...
^

********** Error **********

ERROR: syntax error at or near "IF"
SQL state: 42601
Character: 1

How should this be written ?

Thanks, Jen


From: Raymond O'Donnell <rod(at)iol(dot)ie>
To: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 16:39:12
Message-ID: 4C447FB0.20902@iol.ie
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On 19/07/2010 17:33, Jennifer Trey wrote:
> I can't figure out the correct syntax...
>
> I have this, but it just keeps complaining about the IF
>
> IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
> table_name = 'post_codes')
>
> THEN
>
> CREATE TABLE post_codes
> (
> area character varying(10) NOT NULL,
> district character varying(10) NOT NULL,
> sector character varying(10) NOT NULL,
> CONSTRAINT post_codes_pkey PRIMARY KEY (area, district, sector)
> )
> WITH (
> OIDS=FALSE
> );
> ALTER TABLE post_codes OWNER TO postgres;
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - - - - - - - - - - - -
>
> ERROR: syntax error at or near "IF"
> LINE 1: IF NOT EXISTS (SELECT table_name FROM information_schema.tab...
> ^

> How should this be written ?

I don't think you can use the "IF" like this in a normal query. You
could write a pl/pgsql function instead to do this..

Ray.


From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 16:40:51
Message-ID: AANLkTikrqAwq63e5qAuuP9FU7ce-gWEciaepzRgYORon@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Hello

you can use IF statement only inside plpgsql function. CREATE TABLE
doesn't support clause IF.

Regards

Pavel Stehule

2010/7/19 Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>:
> I can't figure out the correct syntax...
> I have this, but it just keeps complaining about the IF
> IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
> table_name = 'post_codes')
> THEN
> CREATE TABLE post_codes
> (
>   area character varying(10) NOT NULL,
>   district character varying(10) NOT NULL,
>   sector character varying(10) NOT NULL,
>   CONSTRAINT post_codes_pkey PRIMARY KEY (area, district, sector)
> )
> WITH (
>   OIDS=FALSE
> );
> ALTER TABLE post_codes OWNER TO postgres;
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - - - - - - - - - -
> ERROR:  syntax error at or near "IF"
> LINE 1: IF NOT EXISTS (SELECT table_name FROM information_schema.tab...
>         ^
> ********** Error **********
> ERROR: syntax error at or near "IF"
> SQL state: 42601
> Character: 1
>
> How should this be written ?
> Thanks, Jen
>


From: Peter Geoghegan <peter(dot)geoghegan86(at)gmail(dot)com>
To: rod(at)iol(dot)ie
Cc: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 16:42:56
Message-ID: AANLkTikzoCmDn9ztDtc9tseCudqmlih9EdlQgkZpBe04@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

>
>> How should this be written ?
>
> I don't think you can use the "IF" like this in a normal query. You could
> write a pl/pgsql function instead to do this..

You can write such a query inline in 9.0, by use of DO...but you
probably just want to define a function for now
--
Regards,
Peter Geoghegan


From: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
To: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 16:53:42
Message-ID: AANLkTin3r_tH-nm0mgwBvxm4vIoHq2rqNQ1xjCwu-EdD@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

You all make it sound so easy :)

How do I write the above using a function?

Cheers, Jen


From: Joe Conway <mail(at)joeconway(dot)com>
To: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 16:58:42
Message-ID: 4C448442.9090103@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On 07/19/2010 09:33 AM, Jennifer Trey wrote:
> I can't figure out the correct syntax...
>
> I have this, but it just keeps complaining about the IF
>
> IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
> table_name = 'post_codes')
>
> THEN
>
> CREATE TABLE post_codes

Probably better to do:

DROP TABLE IF EXISTS post_codes;
CREATE TABLE post_codes(...);

See:
http://www.postgresql.org/docs/8.4/interactive/sql-droptable.html

HTH,

Joe

--
Joe Conway
credativ LLC: http://www.credativ.us
Linux, PostgreSQL, and general Open Source
Training, Service, Consulting, & 24x7 Support


From: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
To: Joe Conway <mail(at)joeconway(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 17:43:10
Message-ID: AANLkTilT5TL3lqv_g22V7cxI9emg4BFyj3v8-s1D7shw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

No.... I don't want to drop it ... there is valuable data in there! I only
want to create it if it doesn't already exist... likely going to happen
first time the application will run. I want to create the table then and
populate. But not the next time.

Should I just let Java throw and exception and catch it ? Write a function
for this would be optimal, although I have no idea what the correct syntax
is.

Cheers, Jen

On Mon, Jul 19, 2010 at 5:58 PM, Joe Conway <mail(at)joeconway(dot)com> wrote:

> On 07/19/2010 09:33 AM, Jennifer Trey wrote:
> > I can't figure out the correct syntax...
> >
> > I have this, but it just keeps complaining about the IF
> >
> > IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
> > table_name = 'post_codes')
> >
> > THEN
> >
> > CREATE TABLE post_codes
>
> Probably better to do:
>
> DROP TABLE IF EXISTS post_codes;
> CREATE TABLE post_codes(...);
>
> See:
> http://www.postgresql.org/docs/8.4/interactive/sql-droptable.html
>
> HTH,
>
> Joe
>
> --
> Joe Conway
> credativ LLC: http://www.credativ.us
> Linux, PostgreSQL, and general Open Source
> Training, Service, Consulting, & 24x7 Support
>
>


From: Said Ramirez <sramirez(at)vonage(dot)com>
To: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
Cc: Joe Conway <mail(at)joeconway(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 17:53:58
Message-ID: 4C449136.4070007@vonage.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Assuming you know the schema name, you could always check the catalog table, something like
select count(*) from pg_tables where schemaname= 'foo' and tablename='bar'
If it returns, then you know a table by the name foo.bar exists. if not you can create it.
-Said

Jennifer Trey wrote:
> No.... I don't want to drop it ... there is valuable data in there! I only
> want to create it if it doesn't already exist... likely going to happen
> first time the application will run. I want to create the table then and
> populate. But not the next time.
>
> Should I just let Java throw and exception and catch it ? Write a function
> for this would be optimal, although I have no idea what the correct syntax
> is.
>
> Cheers, Jen
>
>
>
> On Mon, Jul 19, 2010 at 5:58 PM, Joe Conway <mail(at)joeconway(dot)com> wrote:
>
>> On 07/19/2010 09:33 AM, Jennifer Trey wrote:
>>> I can't figure out the correct syntax...
>>>
>>> I have this, but it just keeps complaining about the IF
>>>
>>> IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
>>> table_name = 'post_codes')
>>>
>>> THEN
>>>
>>> CREATE TABLE post_codes
>> Probably better to do:
>>
>> DROP TABLE IF EXISTS post_codes;
>> CREATE TABLE post_codes(...);
>>
>> See:
>> http://www.postgresql.org/docs/8.4/interactive/sql-droptable.html
>>
>> HTH,
>>
>> Joe
>>
>> --
>> Joe Conway
>> credativ LLC: http://www.credativ.us
>> Linux, PostgreSQL, and general Open Source
>> Training, Service, Consulting, & 24x7 Support
>>
>>
>


From: Steve Atkins <steve(at)blighty(dot)com>
To: PostgreSQL List <pgsql-general(at)postgresql(dot)org>
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 17:57:30
Message-ID: FD3B66B0-64FD-43C3-9F6E-1A8A6868DC48@blighty.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general


On Jul 19, 2010, at 10:43 AM, Jennifer Trey wrote:

> No.... I don't want to drop it ... there is valuable data in there! I only want to create it if it doesn't already exist... likely going to happen first time the application will run. I want to create the table then and populate. But not the next time.
>
> Should I just let Java throw and exception and catch it ? Write a function for this would be optimal, although I have no idea what the correct syntax is.
>
> Cheers, Jen

Try something like this:

create or replace function build_foo_table() returns void as $$
create table foo (bar int);
$$ language sql;

select case when (select count(*) from information_schema.tables where table_name='foo')=0 then build_foo_table() end;

drop function build_foo_table();

Cheers,
Steve


From: Joe Conway <mail(at)joeconway(dot)com>
To: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 18:05:21
Message-ID: 4C4493E1.6070104@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On 07/19/2010 10:43 AM, Jennifer Trey wrote:
> No.... I don't want to drop it ... there is valuable data in there! I
> only want to create it if it doesn't already exist... likely going to
> happen first time the application will run. I want to create the table
> then and populate. But not the next time.

Sorry -- didn't understand that from your original post. How 'bout
something like:

8<---------------------
CREATE OR REPLACE FUNCTION
conditional_create_table(schemaname text, tablename text, create_sql
text, tbl_owner text)
RETURNS text AS $$
DECLARE
tbl_cnt int;
fqtn text := schemaname || '.' || tablename;
BEGIN
SELECT COUNT(*) INTO tbl_cnt FROM information_schema.tables
WHERE table_schema= schemaname AND table_name=tablename;

IF tbl_cnt < 1 THEN
EXECUTE 'CREATE TABLE ' || fqtn || create_sql;
EXECUTE 'ALTER TABLE ' || fqtn || ' OWNER TO ' || tbl_owner;
RETURN 'CREATE';
ELSE
RETURN 'SKIP';
END IF;
END
$$ LANGUAGE plpgsql STRICT;

SELECT conditional_create_table(
'public',
'post_codes',
'(area character varying(10) NOT NULL,
district character varying(10) NOT NULL,
sector character varying(10) NOT NULL,
CONSTRAINT post_codes_pkey
PRIMARY KEY (area, district, sector)
) WITH (OIDS=FALSE)',
'postgres'
);
conditional_create_table
--------------------------
CREATE
(1 row)

SELECT conditional_create_table(
'public',
'post_codes',
'(area character varying(10) NOT NULL,
district character varying(10) NOT NULL,
sector character varying(10) NOT NULL,
CONSTRAINT post_codes_pkey
PRIMARY KEY (area, district, sector)
) WITH (OIDS=FALSE)',
'postgres'
);
conditional_create_table
--------------------------
SKIP
(1 row)

contrib_regression=# \d public.post_codes
Table "public.post_codes"
Column | Type | Modifiers
----------+-----------------------+-----------
area | character varying(10) | not null
district | character varying(10) | not null
sector | character varying(10) | not null
Indexes:
"post_codes_pkey" PRIMARY KEY, btree (area, district, sector)

8<---------------------

Joe

--
Joe Conway
credativ LLC: http://www.credativ.us
Linux, PostgreSQL, and general Open Source
Training, Service, Consulting, & 24x7 Support


From: Scott Marlowe <scott(dot)marlowe(at)gmail(dot)com>
To: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 18:19:47
Message-ID: AANLkTinz6cua2TtqTr12z1plQJ6bKixWPTI8mOjiCCmB@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Mon, Jul 19, 2010 at 10:33 AM, Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com> wrote:
> I can't figure out the correct syntax...
> I have this, but it just keeps complaining about the IF
> IF NOT EXISTS (SELECT table_name FROM information_schema.tables where
> table_name = 'post_codes')
> THEN
> CREATE TABLE post_codes
> (
>   area character varying(10) NOT NULL,
>   district character varying(10) NOT NULL,
>   sector character varying(10) NOT NULL,
>   CONSTRAINT post_codes_pkey PRIMARY KEY (area, district, sector)
> )
> WITH (
>   OIDS=FALSE
> );

How about something like this:

create function create_table_if_not_exists () returns bool as
$$
BEGIN
BEGIN
Create table test001 (i int, t text);
Exception when duplicate_table THEN
RETURN FALSE;
END;
RETURN TRUE;
END;
$$
Language plpgsql;

When you run it the first time, it comes back true, then false after
that. It's easy enough to wrap that function in another function that
does the data loading.


From: "Igor Neyman" <ineyman(at)perceptron(dot)com>
To: "Joe Conway" <mail(at)joeconway(dot)com>, "Jennifer Trey" <jennifer(dot)trey(at)gmail(dot)com>
Cc: <pgsql-general(at)postgresql(dot)org>
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 20:54:26
Message-ID: F4C27E77F7A33E4CA98C19A9DC6722A2064560C5@EXCHANGE.corp.perceptron.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

> -----Original Message-----
> From: Joe Conway [mailto:mail(at)joeconway(dot)com]
> Sent: Monday, July 19, 2010 12:59 PM
> To: Jennifer Trey
> Cc: pgsql-general(at)postgresql(dot)org
> Subject: Re: Create table if not exists ... how ??
>
> On 07/19/2010 09:33 AM, Jennifer Trey wrote:
> > I can't figure out the correct syntax...
> >
> > I have this, but it just keeps complaining about the IF
> >
> > IF NOT EXISTS (SELECT table_name FROM
> information_schema.tables where
> > table_name = 'post_codes')
> >
> > THEN
> >
> > CREATE TABLE post_codes
>
> Probably better to do:
>
> DROP TABLE IF EXISTS post_codes;
> CREATE TABLE post_codes(...);
>
> See:
> http://www.postgresql.org/docs/8.4/interactive/sql-droptable.html
>
> HTH,
>
> Joe
>
> --
> Joe Conway
> credativ LLC: http://www.credativ.us
> Linux, PostgreSQL, and general Open Source Training, Service,
> Consulting, & 24x7 Support
>

Joe,

What you suggest is completely different from what OP asked.

Jen wants to avoid getting error on CREATE TABLE in case her table
already exists (but proceed with CREATE TABLE, if it doesn't).
What you suggest, will drop the table (IF EXISTS), and then create it
"anew" - what if there is already data in the table?

Regards,
Igor Neyman


From: Joe Conway <mail(at)joeconway(dot)com>
To: Igor Neyman <ineyman(at)perceptron(dot)com>
Cc: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-19 20:55:38
Message-ID: 4C44BBCA.2060109@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On 07/19/2010 01:54 PM, Igor Neyman wrote:
> What you suggest is completely different from what OP asked.
>
> Jen wants to avoid getting error on CREATE TABLE in case her table
> already exists (but proceed with CREATE TABLE, if it doesn't).
> What you suggest, will drop the table (IF EXISTS), and then create it
> "anew" - what if there is already data in the table?

Read on -- we are way past that already...

Joe

--
Joe Conway
credativ LLC: http://www.credativ.us
Linux, PostgreSQL, and general Open Source
Training, Service, Consulting, & 24x7 Support


From: Jennifer Trey <jennifer(dot)trey(at)gmail(dot)com>
To:
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-20 09:18:59
Message-ID: AANLkTim3lvqFmWTmupyvETjhm9bBOrhESjplg7GhGUg4@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Thanks guys.

Joe, I tried ( and learned! ) from your syntax. I didn't have pgsql language
installed but I googled it and figured that part out.

There was an issue with using your way though, you see the constraints
relation also needs to be considered, as if a constraint key already exist,
for any other table, not neccessary for hte table we are creating, then we
are going to get an error, which won't be covered by the count.

So I finally tried Scott's way because it will catch an exception, and I
believe the constraint key exception is included in there. Although I am not
sure, because he is catching a duplicate_table exception ? What is the most
generic exception in postgres ? Throwable in Java ?
http://www.postgresql.org/docs/8.1/interactive/errcodes-appendix.html

create or replace function create_table_if_not_exists (create_sql text)
returns bool as $$
BEGIN
BEGIN
EXECUTE create_sql;

Exception when duplicate_table THEN
RETURN false;
END;
RETURN true;

END;
$$
Language plpgsql;

SELECT create_table_if_not_exists ('CREATE TABLE post_codes
(
area character varying(10) NOT NULL,
district character varying(10) NOT NULL,
sector character varying(10) NOT NULL,
CONSTRAINT post_codes_pkey PRIMARY KEY (area, district, sector)
)
WITH (
OIDS=FALSE
);
ALTER TABLE post_codes OWNER TO postgres;')

Thank you all, Jen


From: Sam Mason <sam(at)samason(dot)me(dot)uk>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Create table if not exists ... how ??
Date: 2010-07-20 13:27:45
Message-ID: 20100720132745.GD7584@samason.me.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Tue, Jul 20, 2010 at 10:18:59AM +0100, Jennifer Trey wrote:
> What is the most generic exception in postgres ? Throwable in Java ?

AFAIR, from programming Java many moons ago, you really don't want to go
about catching the most general exception. The ThreadDeath exception
for instance is derived from Error rather than Exception for this
reason.

That said, maybe you want the "magic" exception type OTHERS, i.e:

EXCEPTION WHEN OTHERS THEN

PG doesn't have as flexible hierarchy as Java, but a match is considered
to have occurred upto the first zero in the error code. So you could
also use syntax_error_or_access_rule_violation or transaction_rollback.

--
Sam http://samason.me.uk/