MySQL create stored procedure syntax with delimiter - mysql

I am trying to create a stored procedure in MySQL using a delimiter like this:
use am;
DELIMITER $$
CREATE PROCEDURE addfields()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE acc INT(16);
DECLARE validId INT DEFAULT 0;
END $$
DELIMITER ;
It gives me an error:
#1304 - PROCEDURE addfields already exists
What is the proper syntax for making a stored procedure with a delimiter and dropping it if it exists first?

Getting started with stored procedure syntax in MySQL (using the terminal):
1. Open a terminal and login to mysql like this:
el#apollo:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql>
2. Take a look to see if you have any procedures:
mysql> show procedure status;
+-----------+---------------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+-----------+---------------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| yourdb | sp_user_login | PROCEDURE | root#% | 2013-12-06 14:10:25 | 2013-12-06 14:10:25 | DEFINER | | utf8 | utf8_general_ci | latin1_swedish_ci |
+-----------+---------------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)
I have one defined, you probably have none to start out.
3. Change to the database, delete it.
mysql> use yourdb;
Database changed
mysql> drop procedure if exists sp_user_login;
Query OK, 0 rows affected (0.01 sec)
mysql> show procedure status;
Empty set (0.00 sec)
4. Ok so now I have no stored procedures defined. Make the simplest one:
mysql> delimiter //
mysql> create procedure foobar()
-> begin select 'hello'; end//
Query OK, 0 rows affected (0.00 sec)
The // will communicate to the terminal when you are done entering commands for the stored procedure. the stored procedure name is foobar. it takes no parameters and should return "hello".
5. See if it's there, remember to set back your delimiter!:
mysql> show procedure status;
->
->
Gotcha! Why didn't this work? You set the delimiter to // remember? Set it back to ;
6. Set the delimiter back and look at the procedure:
mysql> delimiter ;
mysql> show procedure status;
+-----------+--------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+-----------+--------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| yourdb | foobar | PROCEDURE | root#localhost | 2013-12-06 14:27:23 | 2013-12-06 14:27:23 | DEFINER | | utf8 | utf8_general_ci | latin1_swedish_ci |
+-----------+--------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
7. Run it:
mysql> call foobar();
+-------+
| hello |
+-------+
| hello |
+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Hello world complete, lets overwrite it with something better.
8. Drop foobar, redefine it to accept a parameter, and re run it:
mysql> drop procedure foobar;
Query OK, 0 rows affected (0.00 sec)
mysql> show procedure status;
Empty set (0.00 sec)
mysql> delimiter //
mysql> create procedure foobar (in var1 int)
-> begin select var1 + 2 as result;
-> end//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call foobar(5);
+--------+
| result |
+--------+
| 7 |
+--------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Nice! We made a procedure that takes input, modifies it, and does output. Now lets do an out variable.
9. Remove foobar, Make an out variable, run it:
mysql> delimiter ;
mysql> drop procedure foobar;
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> create procedure foobar(out var1 varchar(100))
-> begin set var1="kowalski, what's the status of the nuclear reactor?";
-> end//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call foobar(#kowalski_status);
Query OK, 0 rows affected (0.00 sec)
mysql> select #kowalski_status;
+-----------------------------------------------------+
| #kowalski_status |
+-----------------------------------------------------+
| kowalski, what's the status of the nuclear reactor? |
+-----------------------------------------------------+
1 row in set (0.00 sec)
10. Example of INOUT usage in MySQL:
mysql> select 'ricksays' into #msg;
Query OK, 1 row affected (0.00 sec)
mysql> delimiter //
mysql> create procedure foobar (inout msg varchar(100))
-> begin
-> set msg = concat(#msg, " never gonna let you down");
-> end//
mysql> delimiter ;
mysql> call foobar(#msg);
Query OK, 0 rows affected (0.00 sec)
mysql> select #msg;
+-----------------------------------+
| #msg |
+-----------------------------------+
| ricksays never gonna let you down |
+-----------------------------------+
1 row in set (0.00 sec)
Ok it worked, it joined the strings together. So you defined a variable msg, passed in that variable into stored procedure called foobar, and #msg was written to by foobar.
Now you know how to make stored procedures with delimiters. Continue this tutorial here, start in on variables within stored procedures: http://net.tutsplus.com/tutorials/an-introduction-to-stored-procedures/

Here is the sample MYSQL Stored Procedure with delimiter and how to call..
DELIMITER $$
DROP PROCEDURE IF EXISTS `sp_user_login` $$
CREATE DEFINER=`root`#`%` PROCEDURE `sp_user_login`(
IN loc_username VARCHAR(255),
IN loc_password VARCHAR(255)
)
BEGIN
SELECT user_id,
user_name,
user_emailid,
user_profileimage,
last_update
FROM tbl_user
WHERE user_name = loc_username
AND password = loc_password
AND status = 1;
END $$
DELIMITER ;
and call by, mysql_connection specification and
$loginCheck="call sp_user_login('".$username."','".$password."');";
it will return the result from the procedure.

Here is my code to create procedure in MySQL :
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `procedureName`(IN comId int)
BEGIN
select * from tableName
(add joins OR sub query as per your requirement)
Where (where condition here)
END $$
DELIMITER ;
To call this procedure use this query :
call procedureName(); // without parameter
call procedureName(id,pid); // with parameter
Detail :
1) DEFINER : root is the user name and change it as per your username of mysql localhost is the host you can change it with ip address of the server if you are execute this query on hosting server.
Read here for more detail

I have created a simple MySQL procedure as given below:
DELIMITER //
CREATE PROCEDURE GetAllListings()
BEGIN
SELECT nid, type, title FROM node where type = 'lms_listing' order by nid desc;
END //
DELIMITER;
Kindly follow this. After the procedure created, you can see the same and execute it.

MY SQL STORED PROCEDURE CREATION
DELIMiTER $$
create procedure GetUserRolesEnabled(in UserId int)
Begin
select * from users
where id=UserId ;
END $$
DELIMITER ;

Related

why do I need to reset the delimiter at the end of the stored procedure in mysql

Let's say I have this stored procedure:
Why do I need to reset the delimiter? If I don't reset the delimiter I should be able to use the "$$" instead of the ";"
DELIMITER $$
/* This is a complete statement, not part of the procedure, so use the custom delimiter $$ */
DROP PROCEDURE selectSales$$
/* Now start the procedure code */
CREATE PROCEDURE selectSales()
BEGIN
SELECT * FROM sales;
/* whole procedure ends with the custom delimiter */
END$$
/* I'm not resetting the delimiter, so I should be able to use "$$" instead of ";" */
SELECT * from sales$$ <--- gives syntax error
SELECT * from sales
I don't believe you.
See console output:
mysql> CREATE TABLE sales SELECT 11 id;
Query OK, 1 row affected (0.53 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> DELIMITER $$
mysql> CREATE PROCEDURE selectSales()
-> BEGIN
-> SELECT * FROM sales;
-> END$$
Query OK, 0 rows affected (0.08 sec)
mysql> SELECT * from sales$$
+----+
| id |
+----+
| 11 |
+----+
1 row in set (0.00 sec)
Of course it is possible that you did something not listed in your description...

How to call stored procedure and select the return value at a time on MySQL

on MySQL, I know I can use stored procedure something like this
call someProcedure(#return);
select #return;
but is there some way you can do it with single query ? like this
select #return from (call someProcedure(#return) as sp
thanks in advance :)
Define Procedure
mysql> DELIMITER //
mysql> CREATE PROCEDURE simpleproc(OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END //
call the procedure ->
mysql> CALL simpleproc(#a);
Show Output ->
mysql> SELECT #a;
+------+
| #a |
+------+
| 3 |
+------+1 row in set (0.00 sec)

MYSQL stored procedure not checking the where clause and returning entire table

CREATE DEFINER=`root`#`localhost` PROCEDURE `Viewuser`(IN `userID` VARCHAR(50))
BEGIN
SELECT * FROM `tbl_userdetails` WHERE `UserID`=userID;
END
In the above code the user details of given user id should be return. But it returning the entire table while i execute this stored procedure.
try this method:
mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL simpleproc(#a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #a;
+------+
| #a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
https://dev.mysql.com/doc/refman/5.5/en/create-procedure.html
Got the answer. The field name in table should not be same as variable name.. That is the problem
CREATE DEFINER=root#localhost PROCEDURE Viewuser(IN ID VARCHAR(50))
BEGIN
SELECT * FROM tbl_userdetails WHERE UserID=ID;
END
This is working fine

MySQL Syntax error

I am unable to run a simple script in MySQL. I have reduced the script to just one line.
DELIMITER $$
DECLARE varLocalityName VARCHAR(50);
$$
DELIMITER ;
The error is:
ERROR 1064 (42000) at line 2: 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 varLocalityName VARCHAR(50)' at line 1
$ mysql --version
mysql Ver 14.14 Distrib 5.1.63, for debian-linux-gnu (x86_64) using readline 6.2
Your code block does not define the scope for the declared variables. If within a procedure, they must be between BEGIN and END. Without them, the statement DECLARE varLocalityName VARCHAR(50); becomes an invalid statement to be executed. This statement is equivalent to the statements shown below:
mysql> select current_date();
+----------------+
| current_date() |
+----------------+
| 2012-10-22 |
+----------------+
1 row in set (0.00 sec)
mysql> declare varLocalityName varchar(50);
ERROR 1064 (42000): 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 varLocalityName varchar(50)' at line 1
mysql>
Either you should declare session variables without keyword DECLARE or follow a syntax defined for a stored procedure to use scoped variables.
Example 1: Using session variables:
mysql> set #x = null;
Query OK, 0 rows affected (0.00 sec)
mysql> select #x;
+------+
| #x |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
mysql> delimiter $$
mysql> select current_date() into #x;
-> $$
Query OK, 1 row affected (0.02 sec)
mysql> select #x;
-> $$
+------------+
| #x |
+------------+
| 2012-10-22 |
+------------+
1 row in set (0.00 sec)
Note that you can set/define session variables within a procedure but not DECLARE.
Example 2: Using procedure scoped variables:
mysql>
mysql> delimiter $$
mysql> create procedure some_x()
-> begin
-> declare varLocalityName varchar(50);
->
-> set #sessionDate = null;
-> select #sessionDate;
-> set #sessionDate = current_date();
-> select #sessionDate;
->
-> select varLocalityName;
-> end;
-> $$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql>
mysql> call some_x();
+--------------+
| #sessionDate |
+--------------+
| NULL |
+--------------+
1 row in set (0.00 sec)
+--------------+
| #sessionDate |
+--------------+
| 2012-10-22 |
+--------------+
1 row in set (0.00 sec)
+-----------------+
| varLocalityName |
+-----------------+
| NULL |
+-----------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> select #sessionDate;
+--------------+
| #sessionDate |
+--------------+
| 2012-10-22 |
+--------------+
1 row in set (0.00 sec)
mysql> select varLocalityName;
ERROR 1054 (42S22): Unknown column 'varLocalityName' in 'field list'
mysql>
Also refer to Variables declaration and scope.
I think the problem is that you define $$ as delimiter and then you still try to use ; as the delimiter
I believe this should work:
DELIMITER $$
DECLARE varLocalityName VARCHAR(50)$$
DELIMITER ;
As default MySQL delimiter is ;. You can change it with DELIMITER call and you must use it in the new syntax from then on.
DELIMITER $$
DECLARE varLocalityName VARCHAR(50)$$
SET varLocalityName="xx"$$
SELECT varLocalityName$$
DELIMITER ;
So basically $$ replaces every occurrence of ; (as long as it is not inside the String). If you set DELIMITER **, you would use double stars instead of ;.

Run a query in a MySQL stored procedure if a condition is true

I am using MySQL database and trying to create a stored procedure. How can I make it so that if the result of query1 has no records, then it execute a different query?
Here is what I have so far:
/* CREATE DB */
CREATE DATABASE mydata;
use mydata;
/* TABLE */
CREATE TABLE mydata (
ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(255) NOT NULL,
Value VARCHAR(255) NOT NULL
) ENGINE=InnoDB;
INSERT INTO mydata (Name, Value) VALUES ("testname", "testvalue");
/* STORED PROCEDURE */
delimiter //
CREATE PROCEDURE myproc(IN myTable VARCHAR(255),
IN myValue VARCHAR(255),
IN myValueTwo VARCHAR(255))
BEGIN
SET #iTable=myTable;
SET #iValue=myValue;
SET #iValueTwo=myValueTwo;
SET #query = CONCAT('SELECT Name FROM ', #iTable,
' WHERE Value="', #iValue, '"');
SET #querytwo = CONCAT('SELECT Name FROM ', #iTable,
' WHERE Value="', #iValueTwo, '"');
PREPARE QUERY FROM #query;
EXECUTE QUERY;
END //
delimiter ;
/* CALL */
call myproc("mydata", "testvalue", "");
I want to run a query, and execute a secondary query only if the first has no rows. What is the best way to do this?
This took some work but I made enough adjustments. The problem with your code has nothing to do with your logic but with MySQL Stored Procedure Language itself. When doing dynamic SQL It has scoping issues.
What I did was create a temp table and deposited the returned value in it
Here is some sample data loaded
mysql> drop database if exists user391986;
Query OK, 1 row affected (0.08 sec)
mysql> create database user391986;
Query OK, 1 row affected (0.00 sec)
mysql> use user391986
Database changed
mysql> CREATE TABLE mytable (
-> ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Name VARCHAR(255) NOT NULL,
-> Value VARCHAR(255) NOT NULL
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO mytable (Name,Value) VALUES
-> ('rolando','edge'),('pamela','washington'),
-> ('dominique','wilkins'),('diamond','cutter');
Query OK, 4 rows affected (0.06 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * from mytable;
+----+-----------+------------+
| ID | Name | Value |
+----+-----------+------------+
| 1 | rolando | edge |
| 2 | pamela | washington |
| 3 | dominique | wilkins |
| 4 | diamond | cutter |
+----+-----------+------------+
4 rows in set (0.00 sec)
mysql>
Here is the stored procedure adjusted to catch the return values in a temp table
mysql> delimiter //
mysql> CREATE PROCEDURE myproc(IN myTable VARCHAR(255), IN myValue VARCHAR(255), IN myValueTwo VARCHAR(255))
-> BEGIN
-> DECLARE foundcount INT;
-> DECLARE retval VARCHAR(255);
->
-> SET #iTable=myTable;
-> SET #iValue=myValue;
-> SET #iValueTwo=myValueTwo;
->
-> CREATE TEMPORARY TABLE IF NOT EXISTS mynumber (rv VARCHAR(255)) ENGINE=MEMORY;
-> DELETE FROM mynumber;
->
-> SET retval = 'nothing retrieved';
-> SET #query = CONCAT('INSERT INTO mynumber SELECT Name FROM ', #iTable, ' WHERE Value=''', #iValue, '''');
-> PREPARE QUERY FROM #query;
-> EXECUTE QUERY;
-> DEALLOCATE PREPARE QUERY;
-> SELECT COUNT(1) INTO foundcount FROM mynumber;
-> IF foundcount = 0 THEN
-> SET #querytwo = CONCAT('INSERT INTO mynumber SELECT Name FROM ', #iTable, ' WHERE Value=''', #iValueTwo, '''');
-> PREPARE QUERY FROM #querytwo;
-> EXECUTE QUERY;
-> DEALLOCATE PREPARE QUERY;
-> END IF;
-> SELECT COUNT(1) INTO foundcount FROM mynumber;
-> IF foundcount > 0 THEN
-> SELECT rv INTO retval FROM mynumber;
-> END IF;
-> SELECT retval;
->
-> END //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql>
OK I called the stored procedure three time. The first gets nothing. The second gets the second value. The third gets the first value.
mysql> CALL myproc('mytable','pamela','diamond');
+-------------------+
| retval |
+-------------------+
| nothing retrieved |
+-------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.02 sec)
mysql> CALL myproc('mytable','pamela','wilkins');
+-----------+
| retval |
+-----------+
| dominique |
+-----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> CALL myproc('mytable','edge','wilkins');
+---------+
| retval |
+---------+
| rolando |
+---------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.02 sec)
mysql>
Give it a Try !!!
In mysql you can use the found_rows() built in procedure like this:
el#apollo:~$ mysql -u root -p
Enter password:
mysql> use your_database;
Database changed
mysql> select id from problems;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
4 rows in set (0.00 sec)
mysql> select found_rows();
+--------------+
| found_rows() |
+--------------+
| 4 |
+--------------+
1 row in set (0.00 sec)
In mssql you can use the value ##rowcount. Then you can run the second query only if the first query returned no rows:
EXECUTE QUERY;
IF ##rowcount = 0
BEGIN
PREPARE QUERY FROM #querytwo;
EXECUTE QUERY;
END
In Sql Server, you could run the results into a temporary table and then check the temp table for rows like this:
declare #numberResults int = 0
create table #MyTempTable(...)
insert #MyTempTable
sp_executesql Query
set #numberResults = (select count(*) from #MyTempTable)
if #numberResults = 0
begin
sp_executesql secondQuery
end
My simplest working code
BEGIN
IF test = 'null' THEN
PREPARE QUERY FROM 'SELECT username as name from login';
EXECUTE QUERY;
ELSE
PREPARE QUERY FROM 'SELECT username as name2 from login';
EXECUTE QUERY;
END IF;
END