Mariadb 10.3.29 BEGIN... END statement not working with DECLARE - mysql

i am having an issue getting the following statement to run in Mariadb 10.3.29 and 10.3.13
delimiter |
BEGIN NOT ATOMIC
DECLARE finished int default 0;
DECLARE query varchar(500) default "";
DECLARE curQuery
CURSOR FOR
SELECT CONCAT('ALTER TABLE ',TABLE_SCHEMA ,'.', table_name, ' MODIFY COLUMN `type` tinyint(1) DEFAULT NULL NULL COMMENT "test";')
FROM information_schema.tables WHERE table_name = 'test_table';
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
open curQuery;
executeQuery: LOOP
FETCH curQuery INTO query;
IF finished = 1 THEN
LEAVE executeQuery;
END IF;
prepare stmt from query;
execute stmt;
END LOOP executeQuery;
CLOSE curQuery;
END|
I am getting the following error:
Reason:
SQL Error [1064] [42000]: (conn=54) 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 finished int default 0;
Using dbeaver 21.3.3
According to these docs here: https://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/ i should be able to do this outside of a "stored program" on mariadb 10.1.1+. However, i can get this to run inside of a stored procedure, but i would really like to run this in plain SQL if possible.
Thanks in advance.

You appear to need BEGIN NOT ATOMIC explicitly, which is what the examples show.
fiddle
https://mariadb.com/kb/en/begin-end/:
NOT ATOMIC is required when used outside of a stored procedure. Inside stored procedures or within an anonymous block, BEGIN alone starts a new anonymous block.

Related

wrong syntax to use near 'declare exists_check int'

I'm writing an script to update a db schema, the script is the following:
delimiter //
begin
set #check_exists = 0;
select count(*)
into #check_exists
from information_schema.columns
where table_schema = 'my_app'
and table_name = 'users'
and column_name = 'points';
if (#check_exists = 0) then
alter table my_app.users
add points int not null default 0
end if;
end //
delimiter
when I run it, i get the below error:
Reason:
SQL Error [1064] [42000]: (conn=34) 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 'set #check_exists = 0;
I have already checked the answers the below two posts but none solves my problem.
this question where the solution was to change the delimiter, and to
this question where the solution was to remove the DECLARE keyword and just declare the variable as it is in the MariaDB manual here with set #var int;
I think you need to have a CREATE PROCEDURE before your BEGIN statement. So:
delimiter //
CREATE PROCEDURE UPDATE_SCHEMA()
begin
set #check_exists = 0;
(...your other script here...)
end//
delimiter ;
call UPDATE_SCHEMA();
An additional note: check_exists in your if statement needs a #
According to the BEGIN END documentation here, the syntax is:
BEGIN [NOT ATOMIC]
[statement_list]
END [end_label]
And here is what I did not know:
NOT ATOMIC is required when used outside of a stored procedure. Inside stored procedures or within an anonymous block, BEGIN alone starts a new anonymous block.
As I'm not using the BEGIN END in a stored procedure, I have to add the NOT ATOMIC after the BEGIN keyword.
So the code should look like this:
delimiter //
begin not atomic
set #check_exists = 0;
-- rest of the code here...

How to call procedure inside cursor in MariaDB

I'm new to MariaDB, I only have some experience in MS SQL Server.
I'm trying to call a procedure for every row returned from a query.
But I can't find the error when trying to create a procedure with a cursor.
I'm using Heidy to connect to MariaDB 10.0
CREATE PROCEDURE SetAll()
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE id INT ;
DECLARE cur CURSOR FOR SELECT aID FROM Customers ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
OPEN cur;
testLoop: LOOP
FETCH cur INTO id;
IF done THEN
LEAVE testLoop;
END IF;
CALL SetById(id);
END LOOP testLoop;
CLOSE cur;
END
Error: "/* Error de SQL (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 '' at line 4 */"
My precedure SetById(id) work just fine.

Getting Syntax Error in MySQL Stored Procedure while trying nested Cursors

I have a MySQL Stored Procedure Script in which I am trying to implement a nested cursors . Following is my code
DELIMITER //
DROP PROCEDURE IF EXISTS PopulateStaleEntityTable//
DELETE FROM bucket_stale;
LOAD DATA LOCAL INFILE '/home/centos/mysql1.txt' INTO TABLE bucket_stale;
CREATE PROCEDURE PopulateStaleEntityTable()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE finished_stale INTEGER DEFAULT 0;
DECLARE product_offer_id_var bigint(20) DEFAULT 0;
DECLARE product_offer_group_id_var bigint(20) DEFAULT 0;
DECLARE batch_count INTEGER DEFAULT 0;
DECLARE max_batch_count INTEGER DEFAULT 100;
DECLARE bucket_id_var bigint(10) DEFAULT 0;
DECLARE stale_cursor CURSOR FOR
SELECT staleid FROM bucket_stale;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished_stale = 1;
OPEN stale_cursor;
insert_stale : LOOP
FETCH stale_cursor INTO bucket_id_var;
SELECT bucket_id_var;
BEGIN
DECLARE product_cursor CURSOR FOR
SELECT product_offer_id FROM product where bucket_id='1086';
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
OPEN product_cursor;
insert_entity: LOOP
START TRANSACTION;
FETCH product_cursor INTO product_offer_id_var;
SELECT product_offer_group_id INTO product_offer_group_id_var FROM product_offer where id=product_offer_id_var;
INSERT IGNORE INTO stale_cached_entity (entity_type,entity_id,cache_action,created,field_change) VALUES ('PRODUCT_OFFER_GROUP',product_offer_group_id_var, 'UPDATE',now(),'DEFAULT_SUPC_LIST1');
SET batch_count=batch_count+1;
IF batch_count > max_batch_count THEN
COMMIT;
SET batch_count=0;
END IF;
IF finished = 1 THEN
LEAVE insert_entity;
END IF;
END LOOP insert_entity
END;
IF finished_stale = 1 THEN
LEAVE insert_stale;
END IF;
END LOOP insert_stale;
CLOSE stale_cursor;
END//
DELIMITER ;
When i try and run this script it gives the following error
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 'END;
IF finished_stale = 1 THEN
LEAVE insert_stale;
END IF; ' at line 38
I tried to figure out whats wrong but i couldn't . What am I missing ?
The problem lies in this line:
END LOOP insert_entity
If you review the example of cursor code at https://dev.mysql.com/doc/refman/5.7/en/cursors.html you see that END LOOP does not need the label, and it needs a semicolon statement terminator.
Like this:
END LOOP;
I agree with #tadman's comment. I understand some developers who have had experience with Oracle or Microsoft have an expectation of using stored procedures, but frankly, MySQL's stored procedure support sucks so bad you will be happier and more productive writing some simple Python scripts (or any other language).

MySql Stored Procedure Loop Cursor - Syntax error

Where is the syntax error?
DECLARE irid INT DEFAULT 0;
DECLARE tmp_joinid INT DEFAULT 0;
DECLARE loopjoins_eof INT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET loopjoins_eof = TRUE;
START TRANSACTION;
SET irid = (SELECT id FROM `tables` WHERE `adapter_id`=_aid AND `view_id`=_vid AND `name`=_tname);
IF irid IS NOT NULL THEN
DECLARE cur0 CURSOR FOR SELECT `joins`.`id` FROM `joins` WHERE `table_left_id`=irid OR `table_right_id`=irid;
OPEN cur0;
loopjoins: LOOP
FETCH cur0 INTO tmp_joinid;
IF loopjoins_eof THEN
LEAVE loopjoins;
END IF;
-- Lösche Join-Columns
DELETE FROM `join_columns` WHERE `join_id`=tmp_joinid;
END LOOP loopjoins;
CLOSE cur0;
END IF;
COMMIT;
SELECT irid;
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 cur0 CURSOR FOR SELECT joins.id FROM joins WHERE table_left_id=i' at line 12
Thank you
a much better option is to avoid the cursor, you can replace the cursor with something like
DELETE FROM `join_columns`
WHERE `join_id` in
(SELECT `id`
FROM `joins`
WHERE `table_left_id`=irid OR `table_right_id`=irid);
From the manual:
Cursor declarations must appear before handler declarations and after variable and condition declarations.

can't create mysql stored procedure

I'm a bit of a noob when it comes to stored procedures in general, but I'm trying to write the following
Create procedure clone_perms
as
declare #new_id varchar(30), #old_id varchar(30)
declare get_perms cursor for select userspermsUserid, userspermsPermission from users_permissions where userspermsUserid=#old_id
declare #perms varchar(30), #on_off boolean
FETCH get_perms into #perms, #on_off
while(##sqlstatus=0)
BEGIN
if exists ( select 1 from permissions where userspermsUserid=#new_id and userspermsPermID=#perm )
BEGIN
update permissions set userspermsPermission=#on_off where userspermsUserid=#new_id and userspermsPermID=#perm
END
else
BEGIN
insert permissions (userspermsUserID, userspermsPermID, userspermsPermission) values (#new_id, #perms, #on_off)
END
FETCH get_perms into #perms, #on_off
END
CLOSE get_perms
DEALLOCATE CURSOR get_perms
end
. I get the following error when trying to create it:
/* SQL 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 'as declare #new_id varchar(30) declare #old_id varchar(30) declare get_perm' at line 2 */
. Does anyone know what I need to do to make this work?
You need to have BEGIN tag after CREATE PROCEDURE clone_perms and not AS
don't use an # to start local (declared) variable names, that's only for user variables you create with the
SET #varname=value;
statement. you'll also need to terminate your statements with a semicolon. that's the cause of the latest error, there's no ; after your first declare statement.