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

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.

Related

Error CREATE DATABASE cannot run inside a transaction block

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.

How to roll back a transaction on error in PostgreSQL?

I'm writing a script for PostgreSQL and since I want it to be executed atomically, I'm wrapping it inside a transaction.
I expected the script to look something like this:
BEGIN
-- 1) Execute some valid actions;
-- 2) Execute some action that causes an error.
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END; -- A.k.a. COMMIT;
However, in this case pgAdmin warns me about a syntax error right after the initial BEGIN. If I terminate the command there by appending a semicolon like so: BEGIN; it instead informs me about error near EXCEPTION.
I realize that perhaps I'm mixing up syntax for control structures and transactions, however I couldn't find any mention of how to roll back a failed transaction in the docs (nor in SO for that matter).
I also considered that perhaps the transaction is rolled back automatically on error, but it doesn't seem to be the case since the following script:
BEGIN;
-- 1) Execute some valid actions;
-- 2) Execute some action that causes an error.
COMMIT;
warns me that: ERROR: current transaction is aborted, commands ignored until end of transaction block and I have to then manually ROLLBACK; the transaction.
It seems I'm missing something fundamental here, but what?
EDIT:
I tried using DO as well like so:
DO $$
BEGIN
-- 1) Execute some valid actions;
-- 2) Execute some action that causes an error.
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END; $$
pgAdmin hits me back with a: ERROR: cannot begin/end transactions in PL/pgSQL. HINT: Use a BEGIN block with an EXCEPTION clause instead. which confuses me to no end, because that is exactly what I am (I think) doing.
POST-ACCEPT EDIT:
Regarding Laurenz's comment: "Your SQL script would contain a COMMIT. That ends the transaction and rolls it back." - this is not the behavior that I observe. Please consider the following example (which is just a concrete version of an example I already provided in my original question):
BEGIN;
-- Just a simple, self-referencing table.
CREATE TABLE "Dummy" (
"Id" INT GENERATED ALWAYS AS IDENTITY,
"ParentId" INT NULL,
CONSTRAINT "PK_Dummy" PRIMARY KEY ("Id"),
CONSTRAINT "FK_Dummy_Dummy" FOREIGN KEY ("ParentId") REFERENCES "Dummy" ("Id")
);
-- Foreign key violation terminates the transaction.
INSERT INTO "Dummy" ("ParentId")
VALUES (99);
COMMIT;
When I execute the script above, I'm greeted with: ERROR: insert or update on table "Dummy" violates foreign key constraint "FK_Dummy_Dummy". DETAIL: Key (ParentId)=(99) is not present in table "Dummy". which is as expected.
However, if I then try to check whether my Dummy table was created or rolled back like so:
SELECT EXISTS (
SELECT FROM information_schema."tables"
WHERE "table_name" = 'Dummy');
instead of a simple false, I get the same error that I already mentioned twice: ERROR: current transaction is aborted, commands ignored until end of transaction block. Then I have to manually terminate the transaction via issuing ROLLBACK;.
So to me it seems that either the comment mentioned above is false or at least I'm heavily misinterpreting something here.
You cannot use ROLLBACK in PL/pgSQL, except in certain limited cases inside procedures.
You don't need to explicitly roll back in your PL/pgSQL code. Just let the exception propagate out of the PL/pgSQL code, and it will cause an error, which will cause the whole transaction to be rolled back.
Your comments suggest that this code is called from an SQL script. Then the solution would be to have a COMMIT in that SQL script at some place after the PL/pgSQL code. That would end the transaction and roll it back.
I think you must be using an older version, as the exact code from your question works without error for me:
(The above is with PostgreSQL 13.1, and pgAdmin 4.28.)
It also works fine for me, without the exception block:
As per this comment, you can remove the exception block within a function, and if an error occurs, the transaction run within it will automatically be rolled back. That appears to be the case, from my limited testing.

EXECUTE IMMEDIATE in Enterprise Postgres - query returned no rows error

I'm using Enterprise Postgres 9.5 with Oracle Compatibility. I have a problem with the EXECUTE IMMEDIATE command.
Say I have a table with few columns and one of them can accept NULLs. If I do
EXECUTE IMMEDIATE 'select null_col from '||table_name||' where col1=10' into x;
It sends the value to x, if null_col returns any.
When I given the condition col1=19, where 19 is not present in the table, then I get the error like this.
query returned no rows
and my execution stops. So how can I handle that. Oracle doesn't given any error for such statements, whereas EDB does. Please help.
I didn't find any EDB tags, so please tag if you think this is inappropriate question here. Thanks for understanding.

How do I turn on DB2 syntax in HyperSQL (HSQL)?

I am trying to use HSQL for testing. In production, the code runs against a DB2 database. I would like to turn on the DB2 syntax of HSQL and run the production SQL against it (or as much of it as possible).
According to the documentation, in DB2 syntax mode, the nextval for expression is supported.
I've turned on DB2 syntax mode both with the connection property, sql.syntax_db2=true, and with:
set database sql syntax db2 true;
However, I am not able to use nextval for, though the syntax next value for works correctly:
values (next value for test_seq); -- returns the next value
values (nextval for test_seq); -- results in an error
The error is:
Error: user lacks privilege or object not found: NEXTVAL
SQLState: 42501
ErrorCode: -5501
Am I not correctly activating DB2 syntax mode, or am I doing something else wrong? I am logged in as SA, so can it be a privilege issue?
There is a mistake in the documentation. The DUAL table is supported the same way as in Oracle syntax, but NEXTVAL is an Oracle form used as test_seq.NEXTVAL.
The DB2 supports NEXT VALUE FOR test_seq and allows NEXTVAL as an alternative to NEXT VALUE. This will be supported in the next release of HSQLDB.

T-SQL compilation issue for simple query involving DMV

For some reason, the following query which uses the sys.dm_exec_requests DMV and the sys.dm_exec_sql_text DMV fails to compile:
SELECT er.session_id, es.[text]
FROM sys.dm_exec_requests AS er
CROSS APPLY sys.dm_exec_sql_text(er.[sql_handle]) AS es
The query excerpt above is part of a much larger (and more complex) query which fails, because this smaller query will not execute, giving me the syntax error:
Msg 102, Level 15, State 1, Line 3 Incorrect syntax near '.'.
The query seems simple enough, yet it looks like the T-SQL parser is balking at the er.sql_handle. I thought this might be an escaping issue and tried er.[sql_handle], but sadly got the same error.
I get this error when running it in the context of a DB in SQL Server 2000 compatibility mode. Try running it under the context of one of the system databases instead.
If you are using 2008 or 2008 R2 and EXEC sp_dbcmptlevel 'databasename' give below 90 then use the script below:
ALTER DATABASE databasename SET COMPATIBILITY_LEVEL = 100