Why does this function have a syntax error near DECLARE? - mysql

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.

Related

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.

Error 1064 declaring variable inside trigger

I'm having trouble declaring a variable inside a trigger.
SET DELIMITER ;;
BEGIN
DECLARE qtyNow INT;
SET qtyNow = (
SELECT qty
FROM warehouse
WHERE bin_id = 'GA66'
);
DECLARE need INT;
SET need = (
SELECT min_level
FROM warehouse
WHERE bin_id = 'GA66'
);
END;;
SET DELIMITER ;
I get error #1064 which means illegal syntax. I don't see where I went wrong. I even removed all that bulk and just had
DECLARE qtyNow INT;
And this single line still pops the error.
I see two problems.
One, you have a BEGIN...END block but you are not declaring a trigger.
https://dev.mysql.com/doc/refman/5.7/en/begin-end.html says:
BEGIN ... END syntax is used for writing compound statements, which can appear within stored programs (stored procedures and functions, triggers, and events).
You can't use BEGIN...END as a bare statement. It must be part of a CREATE TRIGGER, CREATE PROCEDURE, CREATE FUNCTION, or CREATE EVENT.
Two, you have two DECLARE statements in your block, with a SET in between.
https://dev.mysql.com/doc/refman/5.7/en/declare.html says:
DECLARE is permitted only inside a BEGIN ... END compound statement and must be at its start, before any other statements.
You are trying to use a second DECLARE after you have done another statement, SET. Do all your DECLAREs up front.

MySQL - Storing variables inside CREATE FUNCTION

I'm trying to figure out how to store variables inside a function in mySQL. I am trying to create a function that capitalizes a field name. Creating a function works if I don't create variables. The problem is this is difficult to read, and is easy to make mistakes with.
CREATE FUNCTION capitalize(string TEXT)
RETURNS TEXT
RETURN CONCAT(UPPER(LEFT(string,1)), LOWER(RIGHT(string, LENGTH(string) - 1)));
When I try to add variables using the DECLARE and SET keywords, it no longer works.
CREATE FUNCTION capitalize(string TEXT)
RETURNS TEXT
DECLARE first_letter TEXT;
DECLARE last_letters TEXT;
SET first_letter = UPPER(LEFT(string,1));
SET last_letters = LOWER(RIGHT(string, LENGTH(string) - 1));
RETURN CONCAT(first_letter, last_letters);
I get this error message
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
I've fiddled around with it, removing semicolons, and double/triple checking parentheses. I've fiddled with BEGIN and END statements but nothing seems to work at all.
I have searched extensively on this topic but cannot figure out where the problem lies.
The body of a CREATE FUNCTION can consist of only a single statement, which is why the first version works and the second doesn't. Fortunately, that single statement can be a compound statement enclosed in a BEGIN ... END block.
You need to enclose the function body in a BEGIN ... END block to allow MySQL to see it as a single statement; you'll also perhaps need to precede and follow it with DELIMITER statements (depending on your client, as Mr. Berkowski points out):
DELIMITER //
CREATE FUNCTION capitalize(string TEXT)
RETURNS TEXT
BEGIN
DECLARE first_letter TEXT;
DECLARE last_letters TEXT;
SET first_letter = UPPER(LEFT(string,1));
SET last_letters = LOWER(RIGHT(string, LENGTH(string) - 1));
RETURN CONCAT(first_letter, last_letters);
END; //
DELIMITER ;
(Note especially the space between the last DELIMITER and the semicolon.)

MYSQL stored procedure

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.

EXISTS and output parameter in stored procedure in mysql

Here is my stored procedure for returning true if any data is found in document details but it generates an 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 '#result = true end if end' at line 5"
create procedure abcde(out result boolean)
begin
if exists(select * from document_details)
then #result = true;
end if
end
Kindly,provide me a solution asap
Besides the fact that you need to use SET to assign a value to a local variable or a parameter, there are other things worth mentioning
you have to have a semicolon after END IF
since EXSITS() returns BOOLEAN you can just directly assign it to your OUT parameter
That being said your stored procedure might look like
CREATE PROCEDURE abcde(OUT result BOOLEAN)
SET result =
(
EXISTS(SELECT *
FROM document_details)
);
Note: now it's just one statement. Therefore you don't even need to change DELIMITER and use BEGIN ... END block.
Here is SQLFiddle demo