1

I have two files that both work fine when executing them in Postgres.

File 1

CREATE TABLE ContractStatusEnum (
    id              SERIAL PRIMARY KEY,
    description         VARCHAR(4000) NOT NULL
);

*File 2

DO $$ BEGIN

    IF NOT EXISTS (SELECT * FROM ContractStatusEnum WHERE id = 1) THEN
    INSERT INTO ContractStatusEnum (id, description) VALUES
        (1, 'Ordered'),
        (2, 'Active'),
        (3, 'Stopped'),
        (4, 'Canceled'),
        (10, 'Inactive');
    END IF;
END $$

However, if I just put them together in one file, it fails with

ERROR: syntax error at or near "DO"
LINE 6: DO $$ BEGIN

On MS SQL I can solve this by creating a new context by putting a GO statement between two scripts. Any clue how to do it in Postgres 9?

3
  • Do is only valid in pgplsql. You can omit the do. Just concatenate the fragments (possibly each statement terminated by a semicolon. The IF NOT EXISTS syntax is invalid: use a WHERE clause instead. Commented Mar 14, 2012 at 11:14
  • The IF NOT EXISTS statement runs fine when I execute the second file in postgres without concatenating. Should I run the complete script in pgplsql? Commented Mar 14, 2012 at 11:16
  • Yes, you can even redirect stdin for psql and use a pipe or '<' to submit a whole script file. Ehh: no, you don't need pgplsql just to submit sql code. just the psql "terminal" executable. Commented Mar 14, 2012 at 11:20

2 Answers 2

3

You need to terminate your DO block with a semicolon.

The following works for me:

DO $$ BEGIN

    IF NOT EXISTS (SELECT * FROM ContractStatusEnum WHERE id = 1) THEN
    INSERT INTO ContractStatusEnum (id, description) VALUES
        (1, 'Ordered'),
        (2, 'Active'),
        (3, 'Stopped'),
        (4, 'Canceled'),
        (10, 'Inactive');
    END IF;
END $$
;

I saved the statements in f1.sql (create table) and f2.sql (do block):

psql (9.1.3)
Type "help" for help.

postgres=> \i f1.sql
CREATE TABLE
postgres=> \i f2.sql
DO
postgres=> 
Sign up to request clarification or add additional context in comments.

Comments

2

Just concatenate the fragments. No / or GO is needed. (in interactive mode for psql a \g may be needed)

CREATE TABLE ContractStatusEnum (
    id              SERIAL PRIMARY KEY,
    description         VARCHAR(4000) NOT NULL
);

    -- File 2

 INSERT INTO ContractStatusEnum (id, description) VALUES 
     (1, 'Ordered'),
     (2, 'Active'),
     (3, 'Stopped'),
     (4, 'Canceled'),
     (10, 'Inactive')
  ;

EDIT: removed the WHERE clause (it is not even valid here) The PK constraint on the table will avoid multiple initialisations anyway.

Another way of concatenation is by means of inclusion. You can create a "master" script, and include the fragments from there. Comes in handy when you want to "comment-out" whole portions.

-- Master script.

\i tables_create.sql
\i procedures_and_functions.sql
\i populate_the_tables.sql
\i do_some_checks.sql

-- EOF

4 Comments

I understand I can get rid of it by omitting the pgplsql, but I have more complicated scripts that require running in that mode.
I don't think pgplsql is valid outside procedures/functions. I would certainly not want it.
@wildplasser: it is certainly valid inside a DO block
Oops. I stand corrected. I never use it; the INSERT will fail because of the PK constraint. (this appears to be a table creation+initialisation script)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.