Error CREATE DATABASE cannot run inside a transaction block - postgresql

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.

Related

PgAdmin won't allow RAISE NOTICE

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.

Query returns Error despite being executed succesfully (Robot Framework / JayDeBeApi)

Using the Keyword Query from the Robot Framework DatabaseLibrary JayDeBeApi in conjunction with DB2 like this: ${results}= Query CREATE TABLE SCHEMANAME.TEST_TEMP (id BIGINT, name VARCHAR(25)) is being executed (table exists afterwards).
But nevertheless RobotFramework throws a FAIL and ${results} contains the Message DatabaseError: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-601, SQLSTATE=42710, SQLERRMC=SCHEMANAME.TEST_TEMP;TABLE, DRIVER=4.14.122 and often even a very simple Message Error after running the same statement.
Running the query above (copy/paste) directly within a database SQL window doesn't return any errors.
How is it possible, in RobotFramework the query is executed successfully but nevertheless an error is thrown?
The error SQLCODE=-601 means that you are trying to create an object that already exists. So when you say that the table exists afterwards, it means that it existed before you ran the statement. I don't know the framework you are using, but the explanation by #pavelsaman in comment seems to be a very likely cause.

Calling external program from PostgreSQL trigger

I would like to execute external program (such as .net c# console) when PostgreSQL trigger is fired. How can I achieve it?
Postgres cannot normally run external programs for security reasons.
The typical solution is to use NOTIFY and have a daemon LISTEN to it. There are solutions for every major scripting language out there ...
Examples for Java from #Craig: How to refresh JPA entities when backend database changes asynchronously?
Relevant manual page for PHP.
Since Postgres 9.3 there is a solution for invoking external programs. It is - for security reasons - limited to superusers and IMHO intended for exporting data, rather than doing a "notification on trigger":
COPY (SELECT 1) TO PROGRAM '/bin/touch /tmp/created_by_postgres'
If you want to actually export data to the invoked programm, you can provide any SELECT or a table name instead of SELECT 1. The query results will then be passed to the invoked program via its standard input.
You can find documentation of the feature in the Postgres docs:
http://www.postgresql.org/docs/9.3/static/sql-copy.html
You can execute external scripts from inside trigger function with an "untrusted" language, like plpythonu.
More details here: https://www.postgresql.org/docs/current/plpython.html
Trigger function example:
CREATE FUNCTION execute_python_script()
RETURNS trigger
AS $$
begin
import subprocess
result = subprocess.run(['/path/to/your/bin/python', '/some_folder/some_sub_folder/script.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
end;
$$
LANGUAGE plpythonu;
Trigger example:
CREATE TRIGGER trigger_name
AFTER INSERT ON table
EXECUTE PROCEDURE execute_python_script();

Calling functions with exec instead of select

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();

What is the purpose of pgScript in PostgreSQL?

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.