65

With SQL Server, I can execute code ad hoc T-SQL code with full procedural logic through SQL Server Management Studio, or any other client. I've begun working with PostgreSQL and have run into a bit of a difference in that PGSQL requires any logic to be embedded in a function.

Is there a way to execute PL/PGSQL code without creating an executing a function?

3 Answers 3

90

Postgres 9

DO $$ 
-- declare
BEGIN
  /* pl/pgsql here */
END $$;
Sign up to request clarification or add additional context in comments.

5 Comments

For anyone who found this answer and tried it only to get "ERROR: syntax error at or near "SELECT"", you need a BEGIN and END. DO $$ BEGIN /* pl/pgsql here */ END $$
But how can that code return a query result? If I put a SELECT in the pl/pgsql part I get ERROR: query has no destination for result data
@Igal: It can't. You cannot return anything from a DO statement. You might raise notices or write to a temporary table or open a cursor as possible workarounds.
little change work for me When i used $$DECLARE instead of $$ ----------------------------------------------------------------------------------------------- DO $$DECLARE srno integer; BEGIN select into srno count(reg_count) from table_name where condition; raise notice 'Desired Count %', srno; END $$;
I was happy to see this work with an EF Core migration
6

No, not yet. Version 9.0 (still alpha) will have this option (do), you a have to wait until it's released.

6 Comments

+1, but I think it was announced for 8.5 - developer.postgresql.org/pgdocs/postgres/release-8.5.html
I thought that 8.5 became 9.0 because of some major features that were implemented...
Yep, 8.5 became 9.0. DO works very nice, just download the alpha and start testing: postgresql.org/download/snapshots
Frank, wish I knew where to download time to play with 9.0 ;-)
Is there documentation for now 9.6.0?
|
2

I struggled to get this working because it's fairly strict about adding semi colons in exactly the right places. But once you get used to that it works well. Besides the inability to return records of course, however you can raise notices & exceptions and do the other workarounds like using temp tables as @ErwinBrandstetter pointed out in a comment above.

e.g.:

DO 
$$
BEGIN
  IF EXISTS(SELECT 'any rows?' 
              FROM {your_table} 
              WHERE {your_column} = 'blah')
  THEN
      RAISE NOTICE 'record exists';
  ELSE
      RAISE EXCEPTION 'record does not exist';
  END IF;

  DROP TABLE IF EXISTS foo;

  CREATE TEMP TABLE foo AS
  SELECT 'bar'::character varying(5) as baz;
END 
$$;

SELECT * FROM foo;

1 Comment

I think the ability to return rows, similar to SQL Server/Oracle stored procedures, is coming in the next version of PostgreSQL. Why that has taken this long is beyond me.

Your Answer

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