MySQL Stored Procedure with If...else not executing - mysql

CREATE DEFINER=`root`#`localhost` PROCEDURE `Mobile_ForgotPassword`(IN`v_email` VARCHAR(30), IN `v_valid` INT)
NO SQL
IF (v_valid = 0) THEN
SELECT email FROM user_registration WHERE email = v_email;
ELSE
SELECT password FROM user_registration WHERE email = v_email;
END IF;
I have this MySQL Stored procedure and its not working. Whenever i try to execute this script on phpmyadmin, getting error on line 4 that i have syntax error. As i am using phpmyadmin, delimiter already added dynamically and i have a privileges to root account. I tried removing DEFINER but still it isn't working. As per my knowledge, i am not seeing any syntax error in script or i am not getting it. Anyone ?

CREATE DEFINER=`root`#`localhost` PROCEDURE `Mobile_ForgotPassword`(IN `v_email` VARCHAR(30), IN `v_valid` INT)
NO SQL
IF (v_valid = 0) THEN
SELECT email FROM user_registration WHERE email = v_email LIMIT 1;
ELSE
SELECT password FROM user_registration WHERE email = v_email LIMIT 1;
END IF;
Removed default Delimiter from textbox under script editor in phpMyAdmin

You need to add DELIMITER
DELIMITER |
CREATE PROCEDURE `Mobile_ForgotPassword`(IN`v_email` VARCHAR(30), IN `v_valid` INT)
NO SQL
IF (v_valid = 0) THEN
SELECT email FROM user_registration WHERE email = v_email;
ELSE
SELECT PASSWORD FROM user_registration WHERE email = v_email;
END IF;
|
DELIMITER ;

Related

MySQL - Set user password with stored procedure

I want to change an user's password using an stored procedure in MySQL.
Here is the creation code:
CREATE SCHEMA `try` ;
USE try;
CREATE TABLE `users` (
`username` VARCHAR(100) NOT NULL,
`password` VARCHAR(100) NOT NULL,
PRIMARY KEY(`username`));
insert into users values('Admin','pass');
create user 'usertry'#'localhost' identified by 'pass';
grant select on try.* to 'usertry'#'localhost';
grant insert on try.* to 'usertry'#'localhost';
grant update on try.* to 'usertry'#'localhost';
grant delete on try.* to 'usertry'#'localhost';
Until here, everything is good.
Then i created a stored procedure to change the table "users".
DELIMITER $$
CREATE PROCEDURE `changeusers` (
IN user VARCHAR(255),
IN pass VARCHAR(255),
IN newuser VARCHAR(255),
IN newpass VARCHAR(255),
OUT result bool)
BEGIN
if(user= Binary (Select username from users limit 1)
and pass= Binary (Select password from users limit 1))
then
delete from users where username=user;
insert into users values(newuser,newpass);
set result=true;
else
set result=false;
end if;
select result;
END $$ DELIMITER ;
When i call the stored procedure, it works well.
call changeusers('Admin','pass','Admin','new',#result);
call changeusers('Admin','pass','Admin','new',#result) 1 row(s) returned 0.141 sec / 0.000 sec
Then i tried to change the stored procedure to set the user's password same as the password in the users table.
DELIMITER $$
CREATE PROCEDURE `changeusers` (
IN user VARCHAR(255),
IN pass VARCHAR(255),
IN newuser VARCHAR(255),
IN newpass VARCHAR(255),
OUT result bool)
BEGIN
if(user= Binary (Select username from users limit 1)
and pass= Binary (Select password from users limit 1))
then
delete from users where username=user;
insert into users values(newuser,newpass);
/*The added line*/
set password for 'usertry'#'localhost' = newpass;
/*The added line*/
set result=true;
else
set result=false;
end if;
select result;
END $$ DELIMITER ;
But when i run the new script i got this:
Error Code: 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
'newpass;
set result=true;
else
set result=false;'
at line 13 0.000 sec
I would apreciate any sugestions.
Thanks.
EDIT
Thanks to #Barmar. I was able to do what i want.
Here's the new stored procedure.
DELIMITER $$
CREATE PROCEDURE `changeusers` (
IN user VARCHAR(255),
IN pass VARCHAR(255),
IN newuser VARCHAR(255),
IN newpass VARCHAR(255),
OUT result bool)
BEGIN
if(user= Binary (Select username from users limit 1)
and pass= Binary (Select password from users limit 1))
then
delete from users where username=user;
insert into users values(newuser,newpass);
/*The added line*/
set #stm = CONCAT("set password for 'usertry'#'localhost' = ",newpass);
prepare stmt from #stm;
execute stmt;
deallocate prepare stmt;
/*The added line*/
set result=true;
else
set result=false;
end if;
select result;
END $$ DELIMITER ;
Thank you so much for your help.
I don't think SET PASSWORD allows the password to be a variable, it has to be a literal (or a call to PASSWORD() with a literal parameter. So you need to use a prepared statement:
PREPARE #stmt FROM CONCAT("SET PASSWORD FOR 'usertry'#'localhost' = '", newpass, "'");
EXECUTE #stmt;

MySQL Stored Procedure - IF EXISTS ... THEN returning unexpected result

The below is my Stored Procedure(Routine) to check whether or not a user with Username(input) exists in the database.
Inside the database, I already have a user with Username - 'dev'.
However, when I ran the below routine, it returned me with res = 1, which I expected it to be -1.
I called the routine this way. Please correct me too if I am calling it the wrong way. I am really new to MySQL Routines.
CALL usp_GetUserValidation ('dev', #ErrorCode)
Can any MySQL Routine pros here enlighten me on this? Thank you in advance guys :)
DELIMITER $$
CREATE PROCEDURE usp_GetUserValidation(IN `#Username` VARCHAR(255), OUT `#ErrorCode` INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'To validate user login'
BEGIN
IF EXISTS
(SELECT UserID
FROM mt_User
WHERE UserName = #Username)
THEN
SET #ErrorCode = -1;
ELSE
SET #ErrorCode = 1;
END IF;
SELECT #ErrorCode AS res;
END$$
DELIMITER ;
It was simply your naming conventions for the parameters. It is finicky and does not like User Variable # signs in them.
You are just testing I can see, as you are returning both a resultset with the info and the OUT variable.
drop procedure if exists usp_GetUserValidation;
DELIMITER $$
CREATE PROCEDURE usp_GetUserValidation(IN pUsername VARCHAR(255), OUT pErrorCode INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'To validate user login'
BEGIN
IF EXISTS
(SELECT UserID
FROM mt_User
WHERE UserName = pUsername)
THEN
SET pErrorCode = -1;
ELSE
SET pErrorCode = 1;
END IF;
SELECT pErrorCode AS res;
END$$
DELIMITER ;
Schema:
-- drop table if exists mt_user;
create table mt_User
( UserID int auto_increment primary key,
UserName varchar(100) not null,
unique key(UserName)
);
insert mt_User(UserName) values ('dev');
select * from mt_User;
Test:
set #var1:=-4;
call usp_GetUserValidation('dev',#var1);
-- returns (-1) ---- Yea, we like that
select #var1;
-- (-1)
set #var1:=-4;
call usp_GetUserValidation('dev222',#var1);
-- returns 1 ---- Yea, we like that
select #var1;
-- 1

mysql stored procedure login

I am using mysql and have a procedure for login authentication,
CREATE PROCEDURE CheckPassword (IN username CHAR(8),IN password_p VARCHAR(20), OUT yes_no char(1))
BEGIN
IF EXISTS(SELECT * FROM USER WHERE USER_ID = username AND password = password_p) then
set yes_no = '0';
ELSE
set yes_no = '1';
END IF;
END;
But it mysql warned that having error when creatinng the procedure, it say have the error i nfor line 4, it is the line of "set yes_no = '0';"? I have try this way too,
CREATE PROCEDURE CheckPassword (IN username CHAR(8),IN password_p VARCHAR(20), OUT yes_no char(1))
BEGIN
IF EXISTS(SELECT * FROM USER WHERE USER_ID = username AND password = password_p) then
select '0' into yes_no;
ELSE
select '1' into yes_no;
END IF;
END;
Didn't work too, is that a must to use delimeter when create procedure? and can u tell me statement of calling this procedure,
I think that the problem was that USER is a reserved word. Also, I suggest you use a function, not a procedure (you just want a value to be returned).
This function works:
DELIMITER ||
CREATE FUNCTION CheckPassword (username VARCHAR(8), password_p VARCHAR(20))
RETURNS BOOL
NOT DETERMINISTIC
READS SQL DATA
BEGIN
RETURN EXISTS (SELECT username FROM `USER` WHERE USER_ID = username AND password = password_p);
END;
||
DELIMITER ;
SELECT CheckPassword('a','b');
Try this:
CREATE PROCEDURE `IsUserPasswordValid`(
IN username varchar(50),
IN password_p VARCHAR(20),
OUT yes_no int
)
BEGIN
SELECT count(*) INTO yes_no
FROM USER u
WHERE u.USER_ID = username && u.password = password_p;
END
If it returns 1 then user is valid.

MYSQL: Procedure with if statement

I'm trying to make a routine that first checks a users password, if it's correct it shall return some values from a different table or change some values in a row.
Is this even possible without making two queries that you handle in PHP? First call for the password, check if its correct then allow the user to make the name change.
Here an example of getting the Rows in User with email and password.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `get_user_info`(
IN in_Email VARCHAR(45),
IN in_Pass VARCHAR(45)
)
BEGIN
SELECT * FROM User WHERE Email = in_Email AND Pass = in_Pass;
END
And this is what Ive got so far:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `change_pass`(
in_Email VARCHAR(45),
in_PassOld VARCHAR(45),
in_PassNew VARCHAR(45)
)
BEGIN
SET #PassOld = (SELECT Pass From User WHERE Email = in_Email);
IF(#PassOld = in_PassOld) THEN
UPDATE User SET Pass = in_PassNew WHERE Email = in_Email;
END IF;
ENDND IF;
END
Thanks for all the help!
You should really hash those passwords, use the following code
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `change_pass`(
in_Email VARCHAR(45),
in_PassOld VARCHAR(45),
in_PassNew VARCHAR(45)
)
BEGIN
DECLARE KnowsOldPassword INTEGER;
SELECT count(*) INTO KnowsOldPassword
FROM User
WHERE Email = in_Email AND passhash = SHA2(CONCAT(salt, in_PassOld),512);
IF (KnowsOldPassword > 0) THEN
UPDATE User
SET Passhash = SHA2(CONCAT(salt, inPassNew),512)
WHERE Email = in_Email;
END IF;
END $$
DELIMITER ;
The salt is an extra field in table user that is more or less random, but does not need to be secret. It serves to defeat rainbow tables.
You can set salt to a short string char(10) or randomish data. e.g.
salt = ROUND(RAND(unix_timestamp(now())*9999999999);
You don't need to update the salt, just generate it once and then store it.
For more on this issue see:
Salting my hashes with PHP and MySQL
How should I ethically approach user password storage for later plaintext retrieval?
A comment on your code
IF(#PassOld == in_PassOld) THEN //incorrect
IF(#PassOld = in_PassOld) THEN //correct, SQL <> PHP :-)

mySQL Create Procedure error + general mysql help

Hi
I'm very very new at MySQL and was wondering if anyone could help me out.
I'm trying to build a procedure for my database and am using the following code.
CREATE PROCEDURE `createuser`(username VARCHAR(100), password VARCHAR(100), email VARCHAR(100)) BEGIN
DECLare returnValue int;
IF EXISTS(SELECT 'True' FROM User_Table WHERE(User_Username = username OR User_Email = email))
BEGIN
SET returnValue = 0;
END;
ELSE
BEGIN
SET returnValue = 1;
INSERT into User_Table(User_Username, User_Password,User_Email) VALUES(username, password,email)
END; END;
I'm getting a error on the BEGIN after the if statement. The error is "Bad syntax near "BEGIN SET returnvalue = 0; END ELSE;
Could you please tell me if im using the IF statement correctly in a mysql sence. It seems to work fine on a MSSql server but not on a Mysql.
Would it also be possible to point me in the direction of some good tutorials for this kinda stuff as the main MYSQL website isn't particularity user friendly.
Cheers
Instead of
IF statement
BEGIN
commands;
END
ELSE
BEGIN
commands;
END
use
IF statement THEN
commands;
ELSE
commands;
END IF;
Here is how I would write your procedure (changes may be a mixture of cosmetic changes and actual changes; suggest experimenting to find out which are which)
CREATE PROCEDURE `createuser` ( IN username VARCHAR(100),
IN password VARCHAR(100),
IN email VARCHAR(100)
)
BEGIN
DECLARE returnValue INT;
IF EXISTS (
SELECT 1
FROM User_Table
WHERE User_Username = username OR User_Email = email
) THEN
SET returnValue = 0;
ELSE
SET returnValue = 1;
INSERT INTO User_Table
(User_Username, User_Password, User_Email)
VALUES
(username, password, email);
END IF;
END;
You don't appear to be doing anything with the variable returnValue. You might need to declare this as OUT or INOUT, depending on what you want to do with it. I haven't got experience of using return values for stored procedures.