Two simple MySQL statements causing syntax error - sql

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

Related

Problem with Stored Procedures in PHPmyAdmin

Attempting to perform operations with a random integer in SQL.
The following code works perfectly as intended when run as pure SQL, but triggers a syntax error when attempting to save it into a stored procedure.
SET #sample_count = (SELECT count(*)
FROM cinder_sample);
SELECT #sample_count;
SET #random_ID = (SELECT FLOOR(RAND()*#sample_count));
SELECT #random_ID;
Any ideas as to what could be going wrong?
The exact error triggered is:
"The following query has failed: "CREATE DEFINER=root#localhost PROCEDURE play_random_sp() NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER DELIMITER // SET #sample_count = (SELECT count() FROM cinder_sample)// SELECT #sample_count// SET #random_ID = (SELECT FLOOR(RAND()#sample_count))// SELECT #random_ID"
MySQL said: #1064 - 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 '// SET #sample_count = (SELECT count(*) FROM cinder_sample)// SELECT' at line 1"

DB2 SQL considers IF ELSE condition a DDL statement?

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.

UNNEST function in DB2 is throwing an error

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!!

Error SQL0104 when creating a function in System i V7R1

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 |

Debug SQL in pgAdmin when SQL contains variables

In SQL Server I could copy sql code out of an application and paste it into SSMS, declare & assign vars that exist in the sql and run. yay great debugging scenario.
E.g. (please note I am rusty and syntax may be incorrect):
declare #x as varchar(10)
set #x = 'abc'
select * from sometable where somefield = #x
I want to do something similar with Postgres in pgAdmin (or another postgres tool, any recommendations?) where I can just drop my SQL (params & all) into something that will run against Postgres DB.
I realise you can create pgscript, but it doesn't appear to be very good, for example, if I do the equivalent of above, it doesn't put the single quotes around the value in #x, nor does it let me by doubling them up and you don't get a table out after - only text...
Currently I have a piece of SQL someone has written that has 3 unique variables in it which are used around 6 times each...
So the question is how do other people debug SQL efficiently, preferably in a similar fashion to my SQL Server days.
You can achieve this using the PREPARE, EXECUTE, DEALLOCATE commands for handling statements, which is really what we are talking about here.
For example:
PREPARE test AS SELECT * FROM users WHERE first_name = $1;
EXECUTE test ('paul');
DEALLOCATE test;
Perhaps not as graphical as some may like, but certainly workable.
I would give a shot at writing a SQL function that wraps your query. It can be something as simple as
CREATE OR REPLACE FUNCTION my_function(integer, integer)
RETURNS integer
AS
$$
SELECT $1 + $2;
$$
LANGUAGE SQL;
SELECT my_function(1, 2);
I would do this instead of a PREPARE since it will be simpler to update it. Depending on how complex the function is, you might want to also look at some of the other PL's in Postgres.
SQL procs are notoriously hard to debug. My lame but practical solution has been to write log messages to a log table, like this (please excuse syntax issues):
create table log_message (
log_timestamp timestamp not null default current_timestamp,
message varchar(1000)
);
then add lines to your stored proc like:
insert into log_message (message) values ("The value of x is " || #x);
Then after a run:
select * from log_message order by 1;
It's not pretty, but works in every DB.