When I try to use RAISE NOTICE in a Query tool in PgAdmin I just get "ERROR: syntax error at or near "RAISE"". This is stopping defining a stored procedure which uses RAISE NOTICE.
I have simply typed the following into a Query Tool window:
RAISE NOTICE 'Bob';
I am using PgAdmin 6.3 (the latest), just updated from v4.5 which had the same problem.
RAISE is part of pl/pgsql, Postgres's default procedural language. It is not available in a direct SQL context, or any function or stored procedure defined with LANGUAGE sql rather than LANGUAGE plpgsql.
If you're used to a different DBMS like MySQL or SQL Server, you might expect to have procedural code (variables, conditionals, loops, etc) available by default, but that's not how Postgres works. In order to use procedural code, you need to be inside a function, stored procedure, or DO statement.
Related
I'm using DbUp to deploy to a PostgreSQL-14 database. When I try to create a function or procedure using SQL-language syntax, DbUp throws an Npgsql.PostgresException 42601, claiming there's a syntax error. I've run the below code successfully using pgAdmin, so I'm not sure why DbUp is having a hard time with it (unless it doesn't support postgres 14?)
Here is my script:
CREATE OR REPLACE FUNCTION test_function() RETURNS VARCHAR(11)
LANGUAGE SQL
BEGIN ATOMIC
SELECT 'Hello World';
END;
and here is the error:
ERROR: syntax error at end of input at character 114
STATEMENT: CREATE OR REPLACE FUNCTION test_function() RETURNS VARCHAR(11)
LANGUAGE SQL
BEGIN ATOMIC
SELECT 'Hello World'
I'm aware I could rewrite the function in plpgsql language, but I want the dependency tracking that SQL language offers.
#ChrisKelly thanks, I wasn't aware of this new syntax! Unfortunately this breaks Npgsql's internal SQL parser, since the semicolon causes the statement to be split... I've opened this issue to track this as an Npgsql bug; some workarounds are suggested there.
If you can't use the workarounds in that issue, then as I posted previously you can use this alternative syntax, even if it's inferior (dependency tracking and so on):
CREATE OR REPLACE FUNCTION test_function() RETURNS VARCHAR(11)
LANGUAGE SQL
RETURN 'Hello World';
I am trying to create a database from a Java application running in Micronaut framework using jOOQ.
The code
contextSupplier.get().createDatabaseIfNotExists(this.databaseName).execute();
with a PostgreSQL datasource fails with:
org.jooq.exception.DataAccessException: SQL [do $$ begin create database "mydb"; exception when sqlstate '42P07' then null; end $$]; ERROR: CREATE DATABASE cannot run inside a transaction block
Is there a simple way to turn transactions off within jOOQ just for this statement?
As of jOOQ 3.14, the DSLContext.createDatabaseIfNotExists() method is supported by these dialects (see its #Support annotation):
#Support({AURORA_POSTGRES,COCKROACHDB,MARIADB,MEMSQL,MYSQL,SQLDATAWAREHOUSE,SQLSERVER})
So, this statement is not yet supported in jOOQ for PostgreSQL - if I remember correctly, for this precise reason. Perhaps there's a different way to emulate the statement, but it hasn't been implemented yet.
Is the default way of calling a function select * from my_function()?
I ask because I have built a function that doesn't return anything, just inserts data into a table and (coming from a SQL Server background) it "feels" strange to call it with select * from...
I was expecting something like exec my_function()
use PERFORM statement - http://www.postgresql.org/docs/current/static/plpgsql-statements.html
Sometimes it is useful to evaluate an expression or SELECT query but
discard the result, for example when calling a function that has
side-effects but no useful result value. To do this in PL/pgSQL, use
the PERFORM statement
so it's just
DO $$ BEGIN
PERFORM my_function();
END $$;
PostgreSQL 11:
PostgreSQL 11 supports true stored procedures as pointed out by #AbdisamadKhalif . They support in-procedure transaction control.
Older versions:
Yes, that's the standard way, and yes it's weird.
Usually you'd write such functions as stored procedures and invoke them with the CALL or EXECUTE command. PostgreSQL does not support true stored procedures (multiple result sets, autonomous transactions, and all that) though, only sql-callable user-defined functions.
So the workaround is to SELECT function_name() using the PostgreSQL extension syntax that omits FROM, or SELECT 1 FROM function_name(); to be (somewhat) more standard.
The ODBC driver, JDBC driver, etc understand the {call func_name()} escape syntax and automatically translate it to an underlying SELECT.
You will use from when the function returns a set. If the function returns void just do
select my_function();
I have failed to understand the need for pgScript, which could be executed using pgAdmin tool. When it should be used? What it can do that plpgSQL cannot do? What is equivalent of it in Microsoft SQL Server?
pgScript is a client-side scripting language, while pl/PgSQL runs on the server. This means they have entirely different use cases. For example, PgScript can manage transaction status while pl/PgSQL cannot, but pl/Pgsql can be used to extend the language of SQL while pgScript cannot do that.
Additionally it means the two will handle many other things quite differently ranging from query plans to dynamic SQL, and while pgScript requires round trips between queries pl/Pgsql does not.
One use for pgScript is to define variables and use them later in your SQLs.
For example, you could do something like this:
declare #mytbl, #maxid;
set #mytbl = 'sometable';
set #maxid = 2500;
set #res = select count(*) from #mytbl where id <= #maxid;
print #res;
This approach is to just have any variables you want to change at the top of your script, rather than those getting buried deep inside complex SQL queries.
Of course, pgScript is a feature available only inside PgAdmin III client like #{Craig Ringer} mentioned in his comment.
I used DDL script generator from Toad Data Modeler.
I ran the script using normal query execution in PgAdmin-III but it kept giving me error:
"ERROR: relation "user" already exists SQL state: 42P07".
I ran Execute pgScript in PgAdmin-III and it worked fine.
I have the following MySQL script which I want to implement in PostgreSQL.
SET #statement = search_address_query;
PREPARE dynquery FROM #statement;
EXECUTE dynquery;
DEALLOCATE PREPARE dynquery;
How can I define user defined variable "#statement" using PostgreSQL.
Postgres does not normally use variables in plain SQL. But you can do that, too:
SET foo.test = 'SELECT bar FROM baz';
SELECT current_setting('foo.test');
Read about Customized Options in the manual.
In PostgreSQL 9.1 or earlier you needed to declare custom_variable_classes before you could use that.
However, You cannot EXECUTE dynamic SQL without a PL (procedural language). You would use a DO command for executing ad-hoc statements (but you cannot return data from it). Or use CREATE FUNCTION to create a function that executes dynamic SQL (and can return data in any fashion imaginable).
Be sure to safeguard against SQL injection when using dynamic SQL.
Related:
Is there a way to define a named constant in a PostgreSQL query?