Dashdb/Netezza: SQL syntax errors - sql

I come from a heavy T-SQL background, have been familiarizing myself with IBM Netezza appliance for a customer. I have played with the Netezza emulator 7.1 on Windows, ran DDL, DML, Control, and Transaction statements. Also, I signed up for a trial DashDB on Bluemix cloud.
ISSUE:
I am facing hurdles with the syntax on both Aginity workbench for DashDB and also the RunSQL on Bluemix
These prevent me from writing more complex SQL beyond simple DDL, DML statements. I am quite frustrated about this.
variable declarations
T-SQL:
DECLARE #I AS INTEGER;
I tried this
DECLARE VARIABLE i INTEGER ;
ERROR [42601] [IBM][DB2/LINUXX8664] SQL0104N An unexpected token "INTEGER" was found following "DECLARE i ". Expected tokens may include: "END-OF-STATEMENT".
DECLARE i AS INTEGER;
ERROR [42601] [IBM][DB2/LINUXX8664] SQL0104N An unexpected token "INTEGER" was found following "DECLARE i AS ". Expected tokens may include: "END-OF-STATEMENT".
DECLARE i INTEGER;
ERROR [42601] [IBM][DB2/LINUXX8664] SQL0104N An unexpected token "INTEGER" was found following "DECLARE i ". Expected tokens may include: "END-OF-STATEMENT".
none of these work...I am simply baffled!
this very simple stored procedure sample from does not compile for me
Code:
CREATEPROCEDURE DASH6441.FOO (IN ORDER_DETAIL_CODE_IN VARCHAR(16), IN SALES_STAFF_CODE_IN INTEGER)
LANGUAGESQL
BEGIN
SELECT*FROM DASH6441.EMP;
END;
Error:
ERROR [42601] [IBM][DB2/LINUXX8664] SQL0104N An unexpected token "EMP" was found following "ECT * FROM DASH6441.". Expected tokens may include: "END".
Questions:
is there anything I am missing?
like T-SQL is there any structure for a SQL script, or preliminary directives (e.g. USING <db_name> in T-SQL) the compiler is expecting? I doubt it, but just asking
If you can share a skeleton of a variable declaration, stored procedure, or generic script with all those elements, which you know compiles successfully for you? Maybe I can inspire myself from that
I am facing a showstopper right now with this syntax issue.

You might need to change the default statement separator in runSQL to be something other than the ; character, so that procedures will be processed correctly.
More info on the use of SQL PL in dashDB is here.

for the create procedure issue the problem is as Margriet described the ambiguous statement delimiter. Just use e.g. delimiter '#' after the END statement and set this character in the RunSQL Page before executing the statement.
Regarding your problems with variable declarations: RunSQL allows to run individual SQL statements. Variable declarations are not valid as standalone SQLs, but only within the context of routines, e.g. within the BEGIN..END block of a stored procedure that you create. E.g. see the examples here: https://www.ibm.com/support/knowledgecenter/SS6NHC/com.ibm.swg.im.dashdb.sql.ref.doc/doc/r0004239.html

Related

How to use SET OPTION within a DB2 stored procedure

I read (and tried) that I cannot use WITH UR in DB2 stored procedures. I am told that I can use SET OPTION to achieve the same. However, when I implement it in my stored procedure, it fails to compile (I moved around its location same error). My questions are:
Can I really not use WITH UR after my SELECT statements within a procedure?
Why is my stored procedure failing to compile with the below error
message?
Here is a simplified version of my code:
CREATE OR REPLACE PROCEDURE MySchema.MySampleProcedure()
DYNAMIC RESULT SETS 1
LANGUAGE SQL
SET OPTION COMMIT=*CHG
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE AS (
SELECT 'testValue' as "Col Name"
) WITH DATA
BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_TABLE;
OPEN exitCursor;
END;
END
#
Error Message:
SQL0104N An unexpected token "SET OPTION COMMIT=*CHG" was found
following " LANGUAGE SQL
Here is code/error when I use WITH UR
CREATE OR REPLACE PROCEDURE MySchema.MySampleProcedure()
LANGUAGE SQL
DYNAMIC RESULT SETS 1
--#SET TERMINATOR #
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE AS (
SELECT UTI AS "Trade ID" FROM XYZ WITH UR
) WITH DATA;
BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_TABLE;
OPEN exitCursor;
END;
END
#
line 9 is where the DECLARE GLOBAL TEMPORARY ... is
DB21034E The command was processed as an SQL statement because it was
not a valid Command Line Processor command. During SQL processing it
returned: SQL0109N The statement or command was not processed because
the following clause is not supported in the context where it is
used: "WITH ISOLATION USE AND KEEP". LINE NUMBER=9. SQLSTATE=42601
Specifying the isolation level:
For static SQL:
If an isolation-clause is specified in the statement, the value of that clause is used.
If an isolation-clause is not specified in the statement, the isolation level that was specified for the package when the package was bound to the database is used.
You need to bind the routine package with UR, since your DECLARE GTT statement is static. Before CREATE OR REPLACE use the following in the same session:
CALL SET_ROUTINE_OPTS('ISOLATION UR')
P.S.: If you want to run your routine not only 1 time in the same session without an error, use additional WITH REPLACE option of DECLARE.
If your Db2 server runs on Linux/Unix/Windows (Db2-LUW), then there is no such statement as SET OPTION COMMIT=*CHG , and so Db2 will throw an exception for that invalid syntax.
It is important to only use the matching Db2 Knowledge Centre for your Db2 platform and your Db2-version. Don't use Db2-Z/OS documentation for Db2-LUW development. The syntax and functionalities differ per platform and per version.
A Db2-LUW SQL PL procedure can use with ur in its internal queries, and if you are getting an error then something else is wrong. You have to use with ur in the correct syntax however, i.e in a statement that supports this clause. For your example you get the error because the clause does not appear to be valid in the depicted context. You can achieve the desired result in other ways, one of them being to populate the table in a separate statement from the declaration (e.g insert into session.temp_table("Trade ID") select uti from xyz with ur; ) and other ways are also possible.
One reason to use the online Db2 Knowledge Cenbtre documentation is that it includes sample programs, including sample SQL PL procedures, which are also available in source code form in the sample directory of your DB2-LUW server, in addition to being available on github. It is wise to study these, and get them working for you.

What is the proper way to execute Dynamic SQL?

We have lots of SQL scripts in our codebase, which produce dynamic SQL statements, and we execute these statements against the database with
EXEC (#FINALSQL)
It is declared like this
DECLARE #FINALSQL NVARCHAR(MAX);
In one of our scripts, we now get an error when executing the dynamic SQL:
Error Number: 2812
Error Severity: 16
ErrorState: 62
ErrorMessage: Could not find stored procedure
with the SQL statement following.
The error number is related to the the error message but still couldn't find any related issue of how to resolve this problem.
I have also read this question but it didn't help because I already enclosed dynamic SQL in brackets
calling EXEC() generates error: could not find stored procedure
Any ideas what could have caused the problem?
Update: the use of #FINALSQL is to create Updates for an amount on tables based on condition in the script.
The answer to almost anything dynamic can be found in Erland Sommarskog's
tour de force.
http://www.sommarskog.se/dynamic_sql.html
"Execute" is optional for the first statement in a batch when executing a stored procedure. There is likely some formatting error in the string and the parser is trying to interpret the first word as a procedure name after failing to parse it otherwise.
If you have no option to capture the string, then use an Extended Event session or trace to capture the query for errors.
If it was a real procedure, then I 'd suspect that current database is wrong. A "USE mydatabase;" as the first thing in the string would fix that. But you state this is not the case. Also, the procedure name was not listed in the error message.

How to "select" inside a stored procedure or a UDF in DB2 LUW?

I believe this question is very trivial. I' unable to select rows inside a stored procedure that I defined, nor inside a UDF. Here is the syntax that I used:
Create Or Replace Procedure GenerateSequence(
In InternalUnitID SmallInt,
In ObjectTypeID SmallInt)
Language SQL
Dynamic Result Sets 1
Not Deterministic
No External Action
Modifies SQL Data
Commit On Return Yes
Begin
Select Number
From Sequence
Where InternalUnit=InternalUnitID
And ObjectType=ObjectTypeID;
End
If I try to create the above procedure (by putting the definition in a SQL file and running it). I get the following error message:
DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned:
SQL0104N An unexpected token "Select Number From Sequence Where Intern" was
found following "n Return Yes Begin ". Expected tokens may include: "".
LINE NUMBER=21. SQLSTATE=42601
Any clue what can be the cause of this problem?
My environment is DB2 10.5 Express on Windows.
My problem was that I needed to use a cursor in order to return the result set to the caller of the stored procedure.
References:
CREATE PROCEDURE (SQL) statement
Compound SQL (compiled) statement

DB2 can't create a simple stored procedure

My real stored procedure is much more complex, but DB2 can't even seem to create a dummy stored procedure that does absolutely nothing (that's why I'm posting this dummy procedure). The procedure is as follows
CREATE PROCEDURE SIMPLE_DECL_PROC()
LANGUAGE SQL
BEGIN
DECLARE v varchar(16);//the problem is here
END
I'm getting the following error:
2:59:31 [CREATE - 0 row(s), 0.000 secs] [Error Code: -104, SQL State: 42601]
DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=END-OF-STATEMENT;ECLARE v varchar(16);<psm_semicolon>, DRIVER=3.57.82
The error complains about the declare statement although I can't see anything wrong with it (tried removing the ; at the end but it didn't work).
If I remove the declare statement, the procedure is created successfully.
I tried to do this with DBVisualizer as well as SQL Squirrel.
I'm sure it's something simple that I'm missing but I can't find it. Needless to say, I've checked similar questions here on SO and elsewhere.
And finally, we're using DB2 9.7.
Thanks
Most SQL clients allow to set a so-called statement terminator. This is the character that is at the end of the entire statement. By default most clients use the semicolon (";"). For stored procedures often a different statement terminator needs to be chosen and set. This is because a stored procedure can include multiple SQL statements which are terminated, but only that ouf the entire stored procedure is relevant.

Compound Statement unable to change the delimiter

I am attempting to run a simple compound statement within the Query Editor of DB Solo 4.2.2
It appears I am unable to properly change the end of line delimiter. I am using DB2. Here is a simple example that gives the error:
--#SET TERMINATOR #
BEGIN ATOMIC
DECLARE id INT;
SET id = 10;
END #
--#SET TERMINATOR ;
Error is:
An unexpected token "INT" was found following "N ATOMIC DECLARE id". Expected tokens may include: "END-OF-STATEMENT"
Thanks in advance
DB2 only allows the semicolon to be used as a delimiter in Compound SQL. The syntax you are using appears to only be valid when using the db2batch utility (which comes with DB2 Linux/Unix/Windows).
Here is some relevant information from the Information Center (this is from the z/OS IC):
How to code multiple statements in an SQL procedure
Use a semicolon
character to separate SQL statements within an SQL procedure.
The procedure body has no terminating character. Therefore, if the
procedure contains only one statement, you do not need to put a
semicolon after that statement. If the procedure consists of a set of
nested statements, you do not need to put a semicolon after the
outermost statement.