I'm working on DB2 database and using TOAD to execute the below statement. STRINGARRAY is already created in MYSCHEMA as Arraytype.
BEGIN
DECLARE CASE_ID_LIST MYSCHEMA.STRINGARRAY;
SET CASE_ID_LIST = ARRAY['A001','A002','A003','A004'];
SELECT T.ID,T.NUM FROM UNNEST(CASE_ID_LIST) AS T(ID,NUM);
END
This statement is throwing an error saying "SQL0104N An unexpected token "UNNEST" was found following ....."
My actual intention is to pass arraylist in IN clause of the where condition. I'm trying this select statement to test the use of UNNEST function.
My final query will look something like this:
BEGIN
DECLARE CASE_ID_LIST MYSCHEMA.STRINGARRAY;
SET CASE_ID_LIST = ARRAY['A001','A002','A003','A004'];
SELECT * FROM MYSCHEMA.TABLENAME WHERE CASE_ID IN (SELECT T.NUM FROM UNNEST(CASE_ID_LIST) AS T(NUM));
END
Please advice how I can get this work. Thank you in advance!!
Related
I have the below query that uses variables, however I want to be able to run this and have results shown from the Select statement. All I am getting is a Message "Commands completed Successfully" instead. I have tried tinkering with the advanced Query Options with checking the 'SET NOTEXEC' option but this did not yield results.
DECLARE #ErrorCount AS INTEGER;
DECLARE #MinErrorDateTime AS DATETIME;
SELECT #ErrorCount = COUNT(IBTRANSACTIONID)
,#MinErrorDateTime = MIN(ERRORTIMESTAMP)
FROM PSIBERR
WHERE MESSAGE_NBR <> 0
AND ERRORTIMESTAMP >= DATEADD(mi,-62,GETDATE())
This should work for you.
You need to do an additional select statement. After your query add this. Also, if this were a stored procedure you could add the variables as Output variables to return the values.
Select #ErrorCount as ErrorCount, #MinErrorDateTime as MinErrorDateTime
I am trying to use a simple IF ELSE query to test a feature with DB2 SQL. However when I attempt to execute it, I run into an error stating that I am not allowed to execute DDL statements.
What is throwing me off is that as far as I know, only database structure altering statements are considered DDL statements.
What gives?
Code:
IF 'True' = 'True' THEN
SELECT * FROM RM_TRANSACTION
FETCH FIRST 2 ROWS ONLY
FOR READ ONLY WITH UR
ELSE
SELECT * FROM RM_TRANSACTION
FETCH FIRST 4 ROWS ONLY
FOR READ ONLY WITH UR
END IF
https://imgur.com/a/58RYjpu
The problem is that you can’t ‘select to nowhere’ in a compound statement in DB2. Db2 CLP can return you the result set of a single sql statement, but it doesn’t try to do the same for select statements in a compound statement.
If you want to print the result set from a select statement in a compound statement, you can, for example, declare a cursor, fetch it in a loop, and use dbms_output.put_line calls to print the values of variables.
I am trying to reset my random number seed before executing a SELECT FROM. However, every time I run it, I have to run both statements separately. Ideally, I would like to have the following work:
BEGIN
exec dbms_random.seed(6);
SELECT * FROM myTable
ORDER BY dbms_random.value()
END
I get an error Encountered the symbol DBMS_RANDOM when expecting one of the following :=.(#%; however if I only run exec dbms_random.seed(6); it works.
EXEC[UTE] is a SQLPLUS command, you can not use it into a PLSQL block.
Also, you need an INTO to use a SELECT query within a PLSQL block. If your query can give more than one row, you woud have to use a BULK COLLECT INTO.
Your code could be something like:
DECLARE
something myTable%rowtype;
BEGIN
dbms_random.seed(6);
SELECT *
INTO something
FROM myTable
ORDER BY dbms_random.value();
END;
However, I do not recommend using things like select *; it would be better to explicitly write the columns you need to get.
Also what's the use of an order by in a select into statement which is defined to only return 1 row?
It seems you want to select 1 random row of many which needs a cursor like so:
DECLARE
CURSOR something_cur IS
SELECT *
FROM myTable
ORDER BY dbms_random.value();
something_rec something_cur%ROWTYPE;
BEGIN
dbms_random.seed(6);
OPEN something_cur;
FETCH something_cur INTO something_rec;
CLOSE something_cur;
END;
/
I'm creating a SQL function on System i V7R1:
CREATE FUNCTION MYSCHEMA.GROUPDIBAS(v_code VARCHAR(50))
RETURNS VARCHAR(2048)
LANGUAGE SQL
BEGIN
DECLARE str VARCHAR(2048);
SET str = '';
FOR row AS (
SELECT
FIELD2
FROM MYSCHEMA.DIBAS
WHERE FIELD1 = v_code
)
DO
SET str = 'Bubi'; --I removed many statements to make clear the problem doesn't come from them
END FOR;
RETURN str;
END
;
I execute it with "Run SQL script" tool, which is part of the iSeries Navigator V7R1.
It works on another V7R1 server (using iSeries Navigator V5R4), but not in that one where I'm working now. It fails with this message:
SQL State: 42601
Vendor Code: -104
Message: [SQL0104] Token <END-OF-STATEMENT> was not valid. Valid tokens: ;.
Cause . . . . . : A syntax error was detected at token <END-OF-STATEMENT>.
Token <END-OF-STATEMENT> is not a valid token. A partial list of valid tokens is ;.
This list assumes that the statement is correct up to the token.
The error may be earlier in the statement, but the syntax of the statement appears to be valid up to this point.
Recovery . . . : Do one or more of the following and try the request again:
-- Verify the SQL statement in the area of the token <END-OF-STATEMENT>. Correct the statement.
The error could be a missing comma or quotation mark, it could be a misspelled word, or it could be related to the order of clauses.
-- If the error token is <END-OF-STATEMENT>, correct the SQL statement because it does not end with a valid clause.
If I remove the FOR block, it works.
Moreover if I execute the statement with 5250 Emulator, command STRSQL, it works. So it seems like a bug in "Run SQL script" client.
Any hint will be appreciated!
The issue is with the FOR statement. The query analyzer is inconsistent on when the cursor-name CURSOR FOR is optional and when it is required even though the documentation states if it is not specifified a unique cursor name is generated. SQL submitted via the IBM Access Navigator Run Scripts utility require it.
The parenthesis are also incorrect but sometimes they are accepted (STRSQL, Navigator Run SQL Scripts) and sometimes they aren't (DBVisualizer/JDBC).
TIL there must be a different query analyzer running depending on the source of the query.
CREATE FUNCTION MYSCHEMA.GROUPDIBAS(v_code VARCHAR(50))
RETURNS VARCHAR(2048)
LANGUAGE SQL
BEGIN
DECLARE str VARCHAR(2048);
SET str = '';
FOR row AS C1 CURSOR FOR
SELECT
FIELD2
FROM MYSCHEMA.DIBAS
WHERE FIELD1 = v_code
DO
SET str = 'Bubi'; --I removed many statements to make clear the problem doesn't come from them
END FOR;
RETURN str;
END
Given the tests made by #JamesA and me, I fear the problem can be in the Program Temporary Fix (PTF) that this server hasn't and the other ones have. Specifically, running WRKPTFGRP command, I can guess it probably misses this PTF group:
PTF group Level Text
SF99701 5 DB2 FOR IBM I
Unfortunately I can't try installing it now :(.
In the session properties of your IDE change the Statement Separator field value from ; to | then reconnect your session. then use | instead of ;. this way you can run your statement or procedure or function.
usage example,
CREATE FUNCTION MYSCHEMA.GROUPDIBAS(v_code VARCHAR(50))
RETURNS VARCHAR(2048)
LANGUAGE SQL
BEGIN
DECLARE str VARCHAR(2048);
SET str = '';
FOR row AS C1 CURSOR FOR
SELECT
FIELD2
FROM MYSCHEMA.DIBAS
WHERE FIELD1 = v_code
DO
SET str = 'Bubi'; --I removed many statements to make clear the problem doesn't come from them
END FOR;
RETURN str;
END |
I'm confounded. The following MySQL query:
SET #a := 0;
SELECT *
FROM users;
Gives the error:
Invalid query: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM users' at line 2`
When I switch the order of the statements, I get the same error, again on line 2 (even though I switched them)
However, either line by themselves runs fine. What could possibly cause this?
I bet you're trying to perform this query in the mysql_query() (or some similar function from any programming language), but it accepts only single query. So the solution is to split this queries into 2 calls.
you can do it in one query as follows:
The trick
select #a:=#a+1, u.*
from
users u
join (select #a:=0) a
or be adventerous and use a stored procedure so it's always a single call :P
Stored procedure
drop procedure if exists list_users;
delimiter #
create procedure list_users()
begin
set #a = 0;
select #a:=#a+1, u.* from users u;
end #
delimiter ;
call list_users();
PHP script
$conn = new mysqli("localhost", "foo_dbo", "pass", "foo_db", 3306);
$result = $conn->query("call list_users()");
while($row = $result->fetch_assoc()){
...
}
$result->close();
$conn->close();