Syntax Error declaring variables in MariaDB - mysql

I have a problem with the following query:
START TRANSACTION;
INSERT INTO posts
(
-- not relevant
)
VALUES
(
-- insert works as intended
);
COMMIT WORK AND CHAIN;
DECLARE #insertId INT; -- this is where i get the syntax error
SET #insertId = LAST_INSERT_ID();
UPDATE posts
SET guid = CONCAT('foo.bar?p=', #insertId)
WHERE id = #insertId;
-- continue to work with the variable
INSERT INTO postmeta(post_id, key, value)
VALUES
(#insertId, ..., ...),
(#insertId, ..., ...),
(#insertId, ..., ...),
(#insertId, ..., ...);
COMMIT WORK;
Basically I insert a row, and need to update it, using the auto incremented id immediately after the insert (to make sure I get the correct value out of the function LAST_INSERT_ID).
Then I need to fill an other table, also using the auto incremented id. In this use case I figured, that I need to store the value in a variable.
Why do i get the following error message?
"You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DECLARE #insertId INT; SET #insertId = LAST_INSERT_ID();' at line 1"
Is the problem that I don't create a procedure or user defined function?

I did a quick search and found this on the MariaDB website (https://mariadb.com/kb/en/user-defined-variables/):
"Since user-defined variables type cannot be declared, the only way to force their type is using CAST() or CONVERT()"
I think the solution is just removing the declare statement since there are examples on their site making variables without declaring them.
I hope this works, I'm not really familiar with MariaDB!

Related

can I get warnings for name conflicts (shadowing) in mysql procedure

If a local variable has the same name as an argument, the argument is overridden (shadowed). If the local variable is not initialized it will be NULL, regardless of the value passed through the argument. I had a procedure with that situation (below) and there was no warning or error. Is there some setting that will give warnings or errors if variables are shadowed?
CREATE DEFINER=`dev`#`localhost` PROCEDURE `new_empErrShadow`(in idVar int)
BEGIN
DECLARE idVar INT; -- ERROR shadows arg idVar, get null value (name conflict)
insert into Employees values (idVar, 28, 'ttt', 'lastname');
-- try get warning about variable shadow. Doesn't work
show errors;
show warnings;
END
Using MySQL 5.7 but 8.0 is the same according to documentation.
Name Conflicts within Stored Routines in
MySQL :: MySQL 5.7 Reference Manual :: 23.8 Restrictions on Stored Programs
I would recommend that you use consistent naming conventions instead:
CREATE DEFINER=`dev`#`localhost` PROCEDURE `new_empErrShadow` (
in in_idVar int
)
BEGIN
DECLARE p_idVar INT; -- ERROR shadows arg idVar, get null value (name conflict)
insert into Employees values (in_idVar, 28, 'ttt', 'lastname');
-- try get warning about variable shadow. Doesn't work
show errors;
show warnings;
END;
Such consistency will help you prevent the errors yourself.

Syntax error in a compound sql statement around Start Transaction, i guess

I am struggling with this compound mysql. I am using the Start Transaction for the first time. So anything will be really helpful.
START TRANSACTION
INSERT
INTO
p_ucourse(
course_name,
course_goal,
course_time,
course_creator_id,
course_status
)
VALUES(
'This Course',
'Goal of this course',
480,
1,
1
);
SET
ucourse_id = LAST_INSERT_ID();
INSERT
INTO
r_ucourse_module(course_id,
module_id,
rank)
VALUES(ucourse_id, 1, 1);
INSERT
INTO
r_ucourse_eu(
course_id,
lu_id,
rank,
afterclass
)
VALUES(ucourse_id, 1, 1, 0);
COMMIT
And it throws up the following error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INSERT
INTO
p_ucourse(
course_name,
course_goal,
course_time,' at line 2
I am not being able to get the syntax of the thing.
Missing semi-colon at the end of the first line. Ditto with Commit Try:
START TRANSACTION;
..
..
COMMIT;
See START TRANSACTION, COMMIT, and ROLLBACK Syntax for a few examples.
...
...
as for your other issue, consider the below:
create table MyThings
( id int auto_increment primary key,
thing varchar(100) not null
);
insert MyThings(thing) values ('Fred, the pet Anchovy');
SET ucourse_id = LAST_INSERT_ID(); -- Error 1193: unknown sys var ...
SET #ucourse_id = LAST_INSERT_ID(); -- YIPPIE, not a problem (user variable)
So, the first one above (SET ucourse_id) choked, because it was assumed to be a LOCAL Variable (as it did not have an # sign). The whole thing was not running in a stored proc/function (I assumed). Local Variables need to have life breathed into them with a DECLARE.
but...
declare k int; -- error, can't do this outside of a store proc/func etc
So, one should read up on User Variables vs Local Variables, when and how one can use them.
Local Variables: DECLARE can be used in Stored Procedures, Functions, Events, and Triggers. But they need to occur grouped together at the top only, before any commands and typcially right after BEGIN. Otherwise, other errors will occur.
User Variables: (such as #myBirthday) No DECLARE is used with them. They are used free-wheeling with less restrictions, such as when you are just hacking around outside of Stored procs, functions, events, and triggers (but can certainly be used inside of them). Note, these are the only type of variables that will succeed with PREPARE, such as the PREPARE stmt001 FROM #theSql; part of it. This last fact is not typically figured out until one wastes a lot of time with it.

Error #1064 when declaring a variable

I am trying to declare and manipulate a variable in MySQL like this:
DECLARE #tim;
//find the difference between current time and time at which the data was stored in the database
SET #tim=(select TIMEDIFF(NOW(),E.reg_date)
FROM `mytable2` E)
But I get the following error:
error:#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 'DECLARE #tim' at line 1
What is causing this error and how can I avoid it? The MySQL server version is 5.6.17.
As the error message says, your syntax is wrong.
tl;dr: SET the variable, do not DECLARE it.
DECLARE is only used when working with variables in routines such as stored procedures, functions and triggers. See the documentation:
DECLARE is permitted only inside a BEGIN ... END compound statement
and must be at its start, before any other statements.
You are trying to set a user-defined variable outside of a routine:
One way to set a user-defined variable is by issuing a SET statement:
SET #var_name = expr [, #var_name = expr] ...
Everything you need to know about this statement, including quite a bit of information about setting session and global variables, is in the documentation for SET.
select TIMEDIFF(NOW(),E.reg_date) into #tim FROM mytable2 E

use of ':=' fails in select in stored procedure due to variable definition

Why does the use of the assignment operator := fail to parse in this stored procedure (fragment)? In the update statement, in the set median = [select expression], in the expression, the MySQL 5.6 parser reports the error, "[Check]...for the right syntax to use near ':= row + 1 as row, $vol as $vol from univ_members' ".
delimiter //
CREATE PROCEDURE m()
BEGIN
DECLARE row int;
SELECT row := row + 1 AS row;
END //
delimiter ;
Running the select statement the mysql shell also fails, but says, 'row' is not a system variable or 'row' is not a column, depending on whether I try to define it with 'set'.
Do you know of a limitation in a stored procedure that prohibits this, or of such a bug in MySQL 5.6? If so, is there a workaround? Can you suggest an alternative approach?
So, after struggling like a man blinded by darkness, I defined the variable #row in the shell using 'set' (the shell's parser does not allow 'row') and it worked. The parser however does not allow a variable defined in a stored procedure with 'declare' to begin with a '#', but, if defined with 'set', it works, it does allow it to be used as the left-hand value in the :=.
So, it's an issue with variable definition. Evidently, only 'user variables', which must begin with a '#' and must be defined with 'set', can be assigned values with ':='. (See User-Defined Variables)
I find such a nuance that all variables don't share a common behavior when it comes to assignment non-intuitive and incredibly irritating. Am I still missing something?

Special Characters in Scriptella, jexl

I want to extract a text field from a database and insert it into some other database. So while extracting I used the REPLACE(message_text,'\'', '"') while selecting the test. I gave me an error. I changed that from my select statement and did it while initiating the global variable.
etl.globals['message_text'] = message_text;
still I'm getting an error at the insert statement
insert into lcs_al_user_likes(user_id,liked_user_id,post_content,loop_id) values('${etl.globals['posted_by']}','${etl.globals['liked_user_id']}','${etl.gl‌​obals['message_text']}',?batchLoopCounter);
saying
*You have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near 'message_text']}')' at line 1*
I think it is not getting the global variable. That I say because when i print its value using log it just gives me
${etl.globals['message_text']}
as output. So please help me out here.
<query connection-id="lcsDBConnection">
SELECT forum_topic_post_id AS forum_topic_post_id, posted_by AS posted_by,message_text as message_text FROM lcs_tbl_forum_topic_post WHERE like_count>0 LIMIT ?batchSize OFFSET ?queryCounter ;
<script connection-id="jexl">
etl.globals['forum_topic_post_id'] = forum_topic_post_id;
etl.globals['posted_by'] = posted_by;
etl.globals['message_text'] = message_text.replace('\'', '"');
</script>
It looks like the problem is in INSERT statement, you should use prepared statement
parameters escaping:
INSERT INTO lcs_al_user_likes(user_id,liked_user_id,post_content,loop_id) values(?{etl.globals['posted_by']},?{etl.globals['liked_user_id']},?{etl.gl‌​obals['message_text']},?batchLoopCounter);
BTW As I understand, your original problem was quotes breaking the insert statement, so in this case with ?{parameter} syntax you don't need to use replace(...) function at all.