Could anyone help me to solve issues with converting MsSQL to MySQL? It gives a syntax error.
Original Mssql function:
CREATE FUNCTION StrToNum (srt1 varchar(250))
RETURNS real AS
BEGIN
DECLARE t real
IF srt1 IS NOT NULL and ISNUMERIC(srt1)=1 and PATINDEX('%,%',srt1)=0 and
PATINDEX('%e%',srt1)=0
SET t=CONVERT(Money,srt1)
ELSE
SET t=NULL
RETURN t
END
i tried like this as mysql
DELIMITER $$
CREATE FUNCTION StrToNum (srt1 VARCHAR(250))
RETURNS REAL DETERMINISTIC
BEGIN
DECLARE t REAL;
IF srt1 IS NOT NULL AND srt1 > 0 AND POSITION('%,%' IN srt1=0) AND POSITION('%e%' IN srt1=0)
THEN SET t=CONVERT(Money,INT);
ELSE
THEN SET t=NULL; END IF;
RETURN t;
END IF;
END $$
DELIMITER;
This code should parse:
DELIMITER $$
CREATE FUNCTION StrToNum (srt1 VARCHAR(250))
RETURNS REAL DETERMINISTIC
BEGIN
DECLARE t REAL;
IF srt1 IS NOT NULL AND srt1 > 0
AND POSITION('%,%' IN srt1=0)
AND POSITION('%e%' IN srt1=0)
THEN SET t=CONVERT(srt1,signed); --(1)
ELSE
SET t=NULL; END IF; --(2)
RETURN t;
END $$ --(3)
DELIMITER ; --(4)
I'll break it down for you:
CONVERT() takes SIGNED or UNSIGNED as target types. INT doesn't work. (1)
You brought forward a error from your CONVERT() syntax in mssql; you used Money instead of srt1 (1). The reason for the confusion is that CONVERT() in MSSQL and MySQL have their parameters reversed.
ELSE doesn't need (or accept) a THEN keyword after it (2)
You had an extra END IF before the final END$$ (3)
DELIMITER ; requires a space (4)
Related
used the following stored procedure to find reverse of a number , but it is showing error:use the right syntax to use near loop.
DELIMITER //
CREATE PROCEDURE ggrepeat1()
begin
declare num1 int;
declare num2 int;
declare rev int default 0;
set #num1:='&num1';
while num1>0
loop
set #num2:=num1 mod 10;
set #rev:=num2+(rev*10);
set #num1:=floor(num1/10);
end loop;
dbms_output.put_line('Reverse number is: '||rev);
end//
DELIMITER ;
As noted in the comments, you can't use oracle syntax in mysql. Regardless, I think you're over-complicating things. A simpler approach would be to cast your number to a string, reverse it using built-in functions and cast it back to a number:
CREATE FUNCTION reverse_int(num INT)
RETURNS INT DETERMINISTIC
RETURN CAST(REVERSE(CAST(num AS CHAT)) AS INT);
The while loop in mysql should be used in this like.
This is the first problem
while n>0 do
content..
end while
The second problem is
dbms_output.put_line('Reverse number is: '||rev);
In mysql you cannot use the above code.
Instead you can use this
Select 'The reverse of number is 'rev;
So your code would be
DELIMITER //
CREATE PROCEDURE ggrepeat1()
begin
declare num1 int;
declare num2 int;
declare rev int default 0;
set #num1:='&num1';
while num1>0 do
set #num2:=num1 mod 10;
set #rev:=num2+(rev*10);
set #num1:=floor(num1/10);
end while;
Select 'Reverse number is: 'rev;
end//
DELIMITER ;
Define procedure:
DELIMITER $$
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
proc_label:BEGIN
IF tablename IS NULL THEN
SELECT 'Null detect';
LEAVE proc_label;
END IF;
SELECT 'after';
END;
$$
DELIMITER ;
Call Procedure:
CALL SP_Reporting();
Error :
ERROR 1318 (42000): Incorrect number of arguments for PROCEDURE
cds.SP_Reporting ; expected 1, got 0
How pass var by default like SP_Reporting(IN tablename = 'default value' VARCHAR(20))
When you are making your stored procedure, you can assign a value to your input, so there is no need to pass parameters while you are calling the proc.
We usually assign NULL and for making parameters optional, we use this method.
tablename VARCHAR(20) = NULL
Your complete script:
DELIMITER $$
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20) = NULL)
proc_label:BEGIN
IF tablename IS NULL THEN
SELECT 'Null detect';
LEAVE proc_label;
END IF;
SELECT 'after';
END;
$$
DELIMITER ;
EDIT
MySQL is not accepting optional parameters. So one way is to pass NULL value in your stored procedure and check it with IF statement inside your proc.
DELIMITER $$
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
proc_label:BEGIN
IF tablename IS NULL THEN
-- Do something;
ELSE
-- Do something else;
END IF;
END;
$$
DELIMITER ;
You have to pass the table name in the procedure call statement like:
CALL SP_Reporting(table_name);
you can't pass default in call statement.
You can assign default value before calling the procedure.
or use OUT instead of IN as a parameter.
you miss the parameter :tablename
you should like this :
call SP_Reporting('any varchar')
or
call SP_Reporting(null)
I have been sitting with a stored procedure for MySQL for days now, it just won't work, so I thought I'd go back to basic and do a very simple function that checks if an item exists or not.
The problem I had on the first one was that it said END IF is invalid syntax on one of my IF clauses, but not the other two. The second one won't even recognize BEGIN as valid syntax...
Is it I that got everything wrong, or have I stumbled upon a MYSQL Workbench bug? I have Workbench 5.2 (latest version when I'm writing this) and this is the code:
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT)
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
to fix the "begin" syntax error, you have to declare a return value, like this:
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT) RETURNS INT(11)
after doing that, Workbench won't return an error anymore ;o)
You have to specify the return value in signature as well delimiter at the end is missing. So, your function should look like
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT) RETURNS INT
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
$$
DELIMITER $$
CREATE FUNCTION `filmsidan`.`f_lateornot` (movie_id INT)
BEGIN
DECLARE check_val INT;
DECLARE return_val INT;
SELECT stockId
FROM orders
WHERE stockId = movie_id
INTO check_val;
IF check_val <= 0
THEN
SET return_val = 1;
ELSE
SET return_val = 0;
END IF;
RETURN return_val;
END
$$
DELIMITER ;
Add this last thing it works :
$$
DELIMITER ;
it means you are using ( ; ) this in function so for that reason we use it..see
and see also
MySQL - Trouble with creating user defined function (UDF)
I have very simple question but i did't get any simple code to exit from SP using Mysql.
Can anyone share with me how to do that?
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
IF tablename IS NULL THEN
#Exit this stored procedure here
END IF;
#proceed the code
END;
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
proc_label:BEGIN
IF tablename IS NULL THEN
LEAVE proc_label;
END IF;
#proceed the code
END;
If you want an "early exit" for a situation in which there was no error, then use the accepted answer posted by #piotrm. Most typically, however, you will be bailing due to an error condition (especially in a SQL procedure).
As of MySQL v5.5 you can throw an exception. Negating exception handlers, etc. that will achieve the same result, but in a cleaner, more precise manner.
Here's how:
DECLARE CUSTOM_EXCEPTION CONDITION FOR SQLSTATE '45000';
IF <Some Error Condition> THEN
SIGNAL CUSTOM_EXCEPTION
SET MESSAGE_TEXT = 'Your Custom Error Message';
END IF;
Note SQLSTATE '45000' equates to "Unhandled user-defined exception condition". By default, this will produce an error code of 1644 (which has that same meaning). Note that you can throw other condition codes or error codes if you want (plus additional details for exception handling).
For more on this subject, check out:
https://dev.mysql.com/doc/refman/5.5/en/signal.html
How to raise an error within a MySQL function
http://www.databasejournal.com/features/mysql/mysql-error-handling-using-the-signal-and-resignal-statements.html
Addendum
As I'm re-reading this post of mine, I realized I had something additional to add. Prior to MySQL v5.5, there was a way to emulate throwing an exception. It's not the same thing exactly, but this was the analogue: Create an error via calling a procedure which does not exist. Call the procedure by a name which is meaningful in order to get a useful means by which to determine what the problem was. When the error occurs, you'll get to see the line of failure (depending on your execution context).
For example:
CALL AttemptedToInsertSomethingInvalid;
Note that when you create a procedure, there is no validation performed on such things. So while in something like a compiled language, you could never call a function that wasn't there, in a script like this it will simply fail at runtime, which is exactly what is desired in this case!
To handle this situation in a portable way (ie will work on all databases because it doesn’t use MySQL label Kung fu), break the procedure up into logic parts, like this:
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
IF tablename IS NOT NULL THEN
CALL SP_Reporting_2(tablename);
END IF;
END;
CREATE PROCEDURE SP_Reporting_2(IN tablename VARCHAR(20))
BEGIN
#proceed with code
END;
This works for me :
CREATE DEFINER=`root`#`%` PROCEDURE `save_package_as_template`( IN package_id int ,
IN bus_fun_temp_id int , OUT o_message VARCHAR (50) ,
OUT o_number INT )
BEGIN
DECLARE v_pkg_name varchar(50) ;
DECLARE v_pkg_temp_id int(10) ;
DECLARE v_workflow_count INT(10);
-- checking if workflow created for package
select count(*) INTO v_workflow_count from workflow w where w.package_id =
package_id ;
this_proc:BEGIN -- this_proc block start here
IF v_workflow_count = 0 THEN
select 'no work flow ' as 'workflow_status' ;
SET o_message ='Work flow is not created for this package.';
SET o_number = -2 ;
LEAVE this_proc;
END IF;
select 'work flow created ' as 'workflow_status' ;
-- To send some message
SET o_message ='SUCCESSFUL';
SET o_number = 1 ;
END ;-- this_proc block end here
END
Why not this:
CREATE PROCEDURE SP_Reporting(IN tablename VARCHAR(20))
BEGIN
IF tablename IS NOT NULL THEN
#proceed the code
END IF;
# Do nothing otherwise
END;
MainLabel:BEGIN
IF (<condition>) IS NOT NULL THEN
LEAVE MainLabel;
END IF;
....code
i.e.
IF (#skipMe) IS NOT NULL THEN /* #skipMe returns Null if never set or set to NULL */
LEAVE MainLabel;
END IF;
I think this solution is handy if you can test the value of the error field later. This is also applicable by creating a temporary table and returning a list of errors.
DROP PROCEDURE IF EXISTS $procName;
DELIMITER //
CREATE PROCEDURE $procName($params)
BEGIN
DECLARE error INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET error = 1;
SELECT
$fields
FROM $tables
WHERE $where
ORDER BY $sorting LIMIT 1
INTO $vars;
IF error = 0 THEN
SELECT $vars;
ELSE
SELECT 1 AS error;
SET #error = 0;
END IF;
END//
CALL $procName($effp);
I have a function that returns a date string. I need this because I can't use a variable in a view, but I can use a function that returns a variable that I set ahead of time...
So I got all that working, but then I decided that if that I wanted it to return the current date if no date variable was set. I thought the code below wold work, but I get syntax errors...
DELIMITER $$
USE `cc`$$
DROP FUNCTION IF EXISTS `ox_date`$$
CREATE FUNCTION `ox_date`() RETURNS CHAR(50) CHARSET latin1
DECLARE ox VARCHAR(20)
IF #oxdate <1 THEN SET ox = CURDATE$$
ELSE SET ox = #oxdate$$
RETURN ox $$
DELIMITER ;
I tried isnull on that first if, but it wasn't any help.
I'm no expert but here are a few of things I see.
First, you've got
DELIMITER $$
and then use it in the function itself. That DELIMITER line allows you to use the semicolons within the body of the function. Otherwise the ';' would end the CREATE FUNCTION statement prematurely.
Also, the line
DECLARE ox varchar(20)
is missing a semicolon at the end.
And then you're missing the
END IF;
after the else condition.
Also what about the BEGIN END$$ wrapped around the function's definition?
I'd expect a stored function to generally take the form:
DELIMITER $$
DROP FUNCTION IF EXISTS `testdb`.MyFunc$$
CREATE FUNCTION `testdb`.`MyFunc` () RETURNS INT
BEGIN
DECLARE someVar varchar(20);
# some stuff
RETURN something;
END $$
DELIMITER ;
Modifying the guts of the function to suit your needs and setting the return type as appropriate.
Anyway, I'm not an expert but that is what I see and hope that helps.
Why do you need to fiddle with the delimiter? For simple logic prefer the IF function to the IF statement.
CREATE FUNCTION `ox_date`( )
RETURNS CHAR(50) CHARSET latin1
RETURN IF(#oxdate < 1 OR #oxdate IS NULL, CURDATE(),#oxdate)
Else
DELIMITER $$
USE `cc`$$
DROP FUNCTION IF EXISTS `ox_date`$$
CREATE FUNCTION `ox_date`( )
RETURNS CHAR(50) CHARSET latin1
RETURN IF(#oxdate < 1 OR #oxdate IS NULL, CURDATE(),#oxdate)$$
DELIMITER ;