MYSQL stored procedure - mysql

I am writing a stored procedure on MYSQL to check if there are recording matching some criteria and output values.
I am used to write in MSSQLSEVER
here is an excerpt of the procedure:
CREATE PROCEDURE prc1(
IN input VARCHAR(15),
OUT output INT
)
this_proc:
BEGIN
SET output = 0;
DECLARE inputCount INT DEFAULT 0;
SELECT COUNT(name) INTO inputCount FROM table WHERE table.name = input;
IF (inputCount> 0) THEN
SET output= 1;
LEAVE this_proc;
END IF;
END;
i am getting errors at each one of this lines:
SET output = 0;
DECLARE ...
IF ...
END IF;
END;
am i doing any syntax error or something?

Give this a shot. It gets past syntax errors, cleans up labels, points you toward fixing mytablename, wraps with delimiters, shows call.
drop procedure if exists prc1;
DELIMITER $$
CREATE PROCEDURE prc1(
IN input VARCHAR(15),
OUT output INT
)
-- this_proc:
BEGIN
DECLARE inputCount INT;
set input=0;
SET output = 0;
SELECT COUNT(name) INTO inputCount FROM mytablename WHERE name = input; -- fix mytablename
IF (inputCount> 0) THEN
SET output= 1;
-- LEAVE this_proc; -- not necessary, you are about to leave anyway !
END IF;
END;
$$ -- signify end of block
DELIMITER ; -- reset to default delimiter
Test it
call prc1('fred',#myVar);
Delimiters
Delimiters are important to wrap the block of the stored proc creation. The reason is so that mysql understands that the sequence of statements that follow are still part of the stored proc until it reaches the specified delimiter. In the case above, I made up one called $$ that is different from the default delimiter of a semi-colon that we are all used to. This way, when a semi-colon is encountered inside the stored proc during creation, the db engine will just consider it as one the many statements inside of it instead of terminating the stored proc creation. Without doing this delimiter wrapping, one can waste hours trying to create their first stored proc getting Error 1064 Syntax errors. At the end of the create block I merely have a line
$$
which tell mysql that that is the end of my creation block, and then the default delimiter of a semi-colon is set back with the call to
DELIMITER ;
Mysql manual page Using Delimiters with MySqlScript. Not a great manual page imo, but trust me on this one. Same issue when creating Triggers and Events.

Related

Delimeter not working, "Syntax" errors when running .sql from shell

I'm trying to make a simple stored procedure... After exploring a bit, I discover I can't make any procedure at all, not even the simplest.
For exemple, running this specific procedure from the documentation:
DELIMETER ;
DROP PORCEDURE IF EXISTS sp_dorepeat
DELIMETER //
CREATE PROCEDURE sp_dorepeat(p1 INT)
BEGIN
SET #x = 0;
REPEAT SET #x = #x + 1; UNTIL #x > p1 END REPEAT;
END //
DELIMETER ;
Gives me the following error:
Which is basically the same syntax error on every line.
Changing the $$ for // also doesn't have any effect, as suggested here.
It's worth knowing that I'm running the shell as root, so there are no restrictions.
Is there anything wrong with my code? The database is mysql 8.0
Of course you can , but with the right keywords
DELIMETER -> DELIMITER
PORCEDURE -> PROCEDURE

Why is this query failing on an empty line?

I'm getting the 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 '' at line 9 but line 9 has nothing on it and it shows that the error is an empty string in the message.
START TRANSACTION;DROP PROCEDURE IF EXISTS `ReporteAcumulado`;
CREATE DEFINER = CURRENT_USER PROCEDURE `ReporteAcumulado`(in Tipo int,in dtInicio date,in dtFin date,in dtmensual date)
SQL SECURITY INVOKER
BEGIN
if Tipo=0 then
END if;
if Tipo=1 then
end if;
END
COMMIT;
The problem is that MySQL is interpreting the semicolons between the BEGIN and END statements as terminating the CREATE PROCEDURE statement, rather than simply being part of the code of the procedure.
You should change the delimiter from ; to something else (// is commonly used when defining MySQL procs). If you don't already have it, add DELIMITER // before the CREATE PROCEDURE statement, and put DELIMITER ; after the END statement for the procedure. I also don't believe that you need to start and commit a transaction when defining a procedure - I've never found it necessary, but perhaps you're doing something different. You also need // after the END. In addition, I've never seen an empty block between IF...THEN...END IF so I'm not sure how that might affect things.
So your code should look something like
DROP PROCEDURE IF EXISTS `ReporteAcumulado`;
DELIMITER //
CREATE DEFINER = CURRENT_USER PROCEDURE `ReporteAcumulado`(in Tipo int,in dtInicio date,in dtFin date,in dtmensual date)
SQL SECURITY INVOKER
BEGIN
if Tipo=0 then
END if;
if Tipo=1 then
end if;
END//
DELIMITER ;
The MySQL documentation for CREATE PROCEDURE explains it this way:
The example uses the MySQL client delimiter command to change the statement delimiter from ; to // while the procedure is being defined. This enables the ; delimiter used in the procedure body to be passed through to the server rather than being interpreted by MySQL itself.

Whats the issue with this stored procedure code ?

The code below is giving many semicolons related errors. I am new to MySql, so clue-less.
CREATE PROCEDURE `sp_get_orderbystatus`(p_status_id int)
BEGIN
declare v int;
if(p_status_id = 1) then
begin
set v = 1;
end;
end if;
END
It looks like you need to change the DELIMITER if you're trying to execute this in mysql cli.
DELIMITER // -- change the delimiter to '//'
CREATE PROCEDURE `sp_get_orderbystatus`(p_status_id int)
DECLARE v INT;
-- the rest of the code of your procedure
END//
DELIMITER ; -- change it back to ';'
Defining Stored Programs
If you use the mysql client program to define a stored program containing semicolon characters, a problem arises. 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.
try:
delimiter //
YOUR PROCEDURE HERE
END//
delimiter ;

Why does this function have a syntax error near DECLARE?

The code is:
DELIMITER $$
CREATE FUNCTION CHECK_AVABILITY(nama CHAR(30))
RETURNS INT(4)
DECLARE vreturn INT(4);
BEGIN
IF nama = 'ika' THEN
SET vreturn = 0;
ELSE
SET vreturn = 1;
END IF
RETURN vreturn;
END $$
The error message is:
ERROR 1064 (42000): You Have an error inyour sql syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE vreturn INT4); BEGIN'
Help is appreciated.
Move DECLARE vreturn INT(4) inside the BEGIN / END block. You probably also need a ; after the END IF.
Additionally, this looks like it is to be a DETERMINISTIC function. Add the DETERMINISTIC keyword before the BEGIN.
DELIMITER $$
CREATE FUNCTION CHECK_AVABILITY(nama CHAR(30))
RETURNS INT(4)
DETERMINISTIC
BEGIN
DECLARE vreturn INT(4);
IF nama = 'ika' THEN
SET vreturn = 0;
ELSE
SET vreturn = 1;
END IF;
RETURN vreturn;
END $$
Here's my findings on the subject:
This is a quote from a manual:
"You need a BEGIN/END block when you have more than one statement in the procedure. You use the block to enclose multiple statements.
But that's not all. The BEGIN/END block, also called a compound statement, is the place where you can define variables and flow of control."
In other words:
(These rules appear to apply to triggers and stored procedures in the same way, as it seems the same syntax is used in both.)
First, notice that a flow control group of keywords such as IF ... END IF or WHILE ... END WHILE is seen as a single statement as far as its termination with a semicolon is concerned, that is, it is terminated as a whole by a single semicolon at the end of it: IF ... END IF; WHILE ... END WHILE;.
Then, if the body of a trigger or stored procedure contains just one stament, and that statement is not a variable declaration nor a flow control group of keywords as above, that statement may not be terminated by a semicolon (;) and not enclosed by a BEGIN ... END block.
On the contrary, if the body of a trigger or stored procedure contains more than one stament, and particularly if it contains variable declarations and/or flow control groups of keywords, then it must be enclosed in a BEGIN ... END block.
Finally, the BEGIN ... END block itself must not be terminated by a semicolon.
Hope this helps.

Trying to learn MySQL and transactions

Over the last couple of days I have tried to write an Stored procedure in MySQL and I have some truble getting it to work. Hope someone here can give me some input :)
The example I post is for asp.Net Membership provider to create a new user. I expect to send email and password to the DB and get an int return to verify that the userdeatils was written to the DB.
I use a MySQL DB 5.1 (I think) and write the SQL to a webinterface.
I got 2 sidequestions, can someone explain that too :):
1) I use a DELIMITER, but do not know what it does.
2) I am not sure if I have to do other things then to set autocommit = 0 to get transactions to work, or if I even have to do that.
I know that I could have used a IF / ELSE statement instead of a transaction, but would like to do it with one to find out how it works. (I expect to use it alot later)
The code I can not get to work:
DELIMITER //
CREATE DEFINER=`websharp_dk`#`%` PROCEDURE `CreateUser`(
IN _username VARCHAR(100),
IN _Password VARCHAR(100))
RETURNS INT
BEGIN
SET autocommit = 0;
DECLARE return_value INT;
BEGIN TRY
START TRANSACTION
INSERT INTO User
(Email
,Password
,Failed_Password_Count
,Creation_Date)
VALUES
(_username
,_Password
,0
,Datetime.Now())
SET return_value = 1;
COMMIT;
END TRY
BEGIN CATCH
ROLLBACK
SET return_value = 0;
END CATCH
BEGIN FINALLY
RETURN return_value;
END FINALLY
END//
DELIMITER ;
Edit:
The error message I get is:
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 'INT BEGIN SET autocommit = 0; DECLARE return_value INT; ' at line 4
To get support for transactions, make sure you are using the InnoDB storage engine rather than the default MyISAM.
As far as that code itself, my first question would be, why are you wrapping that single query in a transaction? Also, what errors are you seeing?
The delimiter redefines what sequence of characters you use to end an sql statement. The entire create procedure is one big statement and you need to tell MySQL where it ends with something (would normally be ';'). But since you have a bunch of other statements in the "body" (between BEGIN and END) of the create procedure statement that all need to be ended too you need to redefine the delimiter so you don't end the create procedure statement at the first ';'.
Without redefining the delimiter, MySQL would think that the create procedure statement looked like this and then begin a new statement:
CREATE DEFINER=`websharp_dk`#`%` PROCEDURE `CreateUser`(
IN _username VARCHAR(100),
IN _Password VARCHAR(100))
RETURNS INT
BEGIN
SET autocommit = 0;
Using DELIMITER ; at the end of the script changes the delimiter back to ';' and is not needed although it's good practice to do so.