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...
Related
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.
I tried to make a simple procedure in MariaDB 10.2 but I encountered an issue regarding variables defining.
I am receiving (conn:107) 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 3 message when I declare a variable.
I read the MariaDB documentation and I it says that a variable is defined like this DECLARE var_name [, var_name] ... type [DEFAULT value]
Where I am wrong? I am coming from Oracle SQL and some sintax is wired for me.
I use Eclipse with MariaDB JDBC to connect on SQL.
CREATE PROCEDURE nom_jobs_insert(IN p_name varchar(100) CHARACTER SET 'utf8')
BEGIN
DECLARE counter INT DEFAULT 0;
SELECT count(*) INTO counter
FROM nom_jobs
WHERE lower(name) = lower(p_name)
IF counter = 1 THEN
INSERT INTO nom_jobs(name) VALUES (p_name);
END IF;
END;
I found the solution.
In MariaDB you have to define a delimiter before create a procedure and you need to mark where the procedure code is finished.
DELIMITER //
CREATE PROCEDURE nom_jobs_insert(IN p_name varchar(100) CHARACTER SET 'utf8')
BEGIN
DECLARE counter INT DEFAULT 0;
SELECT count(*) INTO counter
FROM nom_jobs
WHERE lower(name) = lower(p_name);
IF counter = 1 THEN
INSERT INTO nom_jobs(name) VALUES (p_name);
END IF;
END; //
You have error not in DECLARE expression, add ; after SELECT statement
Here are the clues that point to a missing DELIMITER:
near '' at line 3
Line 3 contains the first ;
When the error says near '', the parser thinks it has run off the end of the "statement".
Put those together -- it thinks that there is one 3-line statement ending with ;. But the CREATE PROCEDURE should be longer than that.
CREATE PROCEDURE nom_jobs_insert(IN p_name varchar(100) CHARACTER SET 'utf8')
IS
DECLARE counter INTEGER DEFAULT 0;
BEGIN
SELECT count(*) INTO counter
FROM nom_jobs
WHERE lower(name) = lower(p_name)
IF counter = 1 THEN
INSERT INTO nom_jobs(name) VALUES (p_name);
END IF;
END;
Hey guys i am facing a problem when i use a variable with a case in mysql.
The code which i have used is
DECLARE vSite VARCHAR(20);
SET vSite = case
when id > 0 then 'sdfsdf'
else 'asd' end as name
from customers;
When i run this code it throws me error like
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 vSite VARCHAR(20)' at line 1: DECLARE vSite VARCHAR(20)
CAN anyone point me where am going wrong..Thanks for your valuable help
You need to declare variables inside a BEGIN END block.
Here is a simple example of a stored procedure
DELIMITER //
CREATE procedure blah(IN customer_id INT,OUT vSite VARCHAR(20))
BEGIN
SELECT CASE WHEN id > 0 THEN 'blah'
ELSE 'mah' END INTO vSite FROM customers WHERE id=customer_id;
END//
DELIMITER ;
CALL blah(3,#somevar);
SELECT #somevar;
I am trying to create a trigger that marks items as deleted when they are inserted into the database.
Sadly I can't get my DECLARE to stop erroring, I have looked at the DECLARE docs and also at a few examples but I must be missing something.
The query I have so far is:
CREATE TRIGGER set_deleted BEFORE INSERT ON customercontact
FOR EACH ROW
BEGIN
DECLARE numrow INT; /* line 4 */
SELECT COUNT(*)
INTO numrow
FROM orders
WHERE NEW.order_id = 1;
if numrow >= 1 THEN
SET new.deleted = 1;
END IF;
END
The error message is showing:
#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 '' at line 4
Thanks for your help and preventing me from defenestrating myself!
Try this:
DELIMITER $$
CREATE TRIGGER set_deleted BEFORE INSERT ON customercontact
FOR EACH ROW
BEGIN
DECLARE numrow INT; /* line 4 */
SELECT COUNT(*)
INTO numrow
FROM orders
WHERE NEW.order_id = 1;
if numrow >= 1 THEN
SET new.deleted = 1;
END IF;
END$$
DELIMITER ;
You need to change the delimiter when you create TRIGGER or STORED PROCEDURE.
By default, MySQL itself recognizes the semicolon as a statement delimiter, so you must redefine the delimiter temporarily to cause MySQL to pass the entire stored program definition to the server. Otherwise, MySQL breaks CREATE TRIGGER, before it reaches the END statement (on the first semicolon, which, in your case, is DECLARE statement).
You can see the documentation for more details:
http://dev.mysql.com/doc/refman/5.5/en/stored-programs-defining.html
I am trying to write trigger in Mysql (5.1), but getting following error, please help.
The error is:
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 '' at line 5.
Purpose for writing trigger:
I am writing application where I am assigning users, and I want to store unassigned usercount to field cluster_count in IX_branchdetails table.After updating the base table.
trigger:
DELIMITER $$
CREATE TRIGGER upd_trg AFTER
UPDATE ON DBNAME.BASETABLE
FOR EACH ROW
BEGIN
DECLARE m_branchcode INTEGER;
DECLARE cnt INTEGER;
DECLARE cursor_branch CURSOR FOR
SELECT DISTINCT branchcode
FROM ix_branchdetails;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open cursor_branch;
my_loop: loop
set done = false;
fetch cursor_branch into m_branchcode;
if done then
leave my_loop;
end if;
select count(1) into cnt from (select count(1) from BASETABLE Where IX_BRANCHCODE = m_branchcode) as temp;
update DBANAME.ix_branchdetails set DBANAME.ix_branchdetails.cluster_count = cnt where DBANAME.ix_branchdetails.BRANCHCODE = m_branchcode;
end loop my_loop;
close cursor_branch;
END $$
DELIMITER ;
I don't see a declare for the done variable:
DECLARE done TINYINT DEFAULT FALSE;
The semicolon (;) is the default delimiter for MySQL statements. To get a procedure/function/trigger defined, we normally see the statement delimiter changed to a string that doesn't appear in the statement:
DELIMITER $$
CREATE PROCEDURE ...
END$$
DELIMITER ;
If the delimiter is not changed from the semicolon, then when MySQL encounters the first semicolon in your procedure/function/trigger, it sees that as the end of the statement, which is not what you want. You want MySQL to see the entire block of code as a single statement.