I'm working on login/register module of my program based on a tutorial I found.
Everything worked fine but then I switched from MSSql to MySql database.
The problem is I can't rewrite my InsertUser procedure. This procedure takes 3 parameters (username, password and email) and can return 3 different values
-1 if username is already used
-2 if email is already used
id of new row if registration is successful
I tried to write it like this:
DELIMITER $$
CREATE PROCEDURE InsertUser(
IN username VARCHAR(50),
IN pass VARCHAR(255),
IN email VARCHAR(50))
BEGIN
IF (SELECT Id FROM Users WHERE UserName=username) THEN
BEGIN
SELECT -1;
END;
ELSEIF (SELECT Id FROM Users WHERE Email=email)
THEN
BEGIN
SELECT -2;
END;
ELSE
BEGIN
INSERT INTO Users (UserName, Password, RegDate, Email) VALUES(username, pass, CURDATE(), email);
SELECT LAST_INSERT_ID();
END;
END IF;
END $$
DELIMITER ;
When I try to create this procedure using the above code from Visual Studio I get error (wrong syntax). However there is no error if I do it from phpmyadmin page. But it doesn't work at all (returns nothing) regardless of arguments I provide. I'm using phpmyadmin page and execute procedure option to test it.
Here is original T-Sql code:
CREATE PROCEDURE [dbo].[Insert_User]
#Username NVARCHAR(20),
#Password NVARCHAR(20),
#Email NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT Id FROM Users WHERE Username = #Username)
BEGIN
SELECT -1 -- Username exists.
END
ELSE IF EXISTS(SELECT Id FROM Users WHERE Email = #Email)
BEGIN
SELECT -2 -- Email exists.
END
ELSE
BEGIN
INSERT INTO [Users]
([Username]
,[Password]
,[Email]
,[RegDate])
VALUES
(#Username
,#Password
,#Email
,GETDATE())
SELECT SCOPE_IDENTITY() -- UserId
END
END
Any ideas?
6.10.1 Using Stored Routines from Connector/Net
...
Unlike the command-line and GUI clients, you are not required to specify a special delimiter when creating stored procedures in Connector/Net.
...
One option in MySQL (command-line):
DELIMITER $$
CREATE PROCEDURE `InsertUser` (
IN `_username` VARCHAR(50),
IN `_pass` VARCHAR(255),
IN `_email` VARCHAR(50)
)
BEGIN
IF (SELECT `Id` FROM `Users` WHERE `UserName` = `_username`) THEN
SELECT -1;
ELSEIF (SELECT `Id` FROM `Users` WHERE `Email` = `_email`) THEN
SELECT -2;
ELSE
INSERT INTO `Users` (`UserName`, `Password`, `RegDate`, `Email`)
VALUES (`_username`, `_pass`, CURDATE(), `_email`);
SELECT LAST_INSERT_ID();
END IF;
END$$
DELIMITER ;
Thank you, but I solved it myself. I don't know why I wanted so badly to use EXISTS function:) I got rid of it and now it works:
BEGIN
IF(SELECT Id FROM Users WHERE UserName=username) IS NOT NULL THEN
SELECT -1;
ELSEIF (SELECT Id FROM Users WHERE Email=email) IS NOT NULL THEN
SELECT -2;
ELSE
INSERT INTO Users(UserName, Password, RegDate, Email) VALUES (username, pass, CURDATE(), email);
SELECT LAST_INSERT_ID();
END IF;
END
Related
I am trying to write stored procedure to insets values and if record exist then select that row but it is giving me invalid use of group statement
I have written below: -
TRY 1:- error :- invalid use of group statement
CREATE DEFINER=`root`#`localhost` PROCEDURE `insusers`(IN enterprise_id varchar(40),IN enterprise_name varchar(40),IN email_id varchar(40))
BEGIN
SELECT COUNT(*) FROM user WHERE email_id = email_id;
IF COUNT(*) < 1 THEN
INSERT INTO user(enterprise_id,user_name,email_id)
VALUES (enterprise_id,enterprise_name,email_id);
SELECT * FROM user WHERE user_id = last_insert_id();
ELSE
SELECT * FROM user WHERE email_id = email_id;
END IF;
END
TRY 2 :- error :- Not able to insert new values
CREATE DEFINER=`root`#`localhost` PROCEDURE `insusers`(IN enterprise_id varchar(40),IN enterprise_name varchar(40),IN email_id varchar(40))
BEGIN
DECLARE count INT DEFAULT 0;
SELECT COUNT(*) INTO count FROM user WHERE email_id = email_id;
IF count < 1 THEN
INSERT INTO user(enterprise_id,user_name,email_id)
VALUES (enterprise_id,enterprise_name,email_id);
SELECT * FROM user WHERE user_id = last_insert_id();
ELSE
SELECT * FROM user WHERE email_id = email_id;
END IF;
END
Please help me with solution.
Thanks in advance.
It is recommended to use BEGIN and END to separate IF clauses, also use # to distinguish between variables and columns. Hope this helps:
CREATE DEFINER=`root`#`localhost` PROCEDURE `insusers`(IN #enterprise_id varchar(40),IN #enterprise_name varchar(40),IN #email_id varchar(40))
BEGIN
IF ((SELECT COUNT(*) FROM user WHERE email_id = #email_id)<1) BEGIN
INSERT INTO user(enterprise_id,user_name,email_id)
VALUES (#enterprise_id,#enterprise_name,#email_id);
SELECT * FROM user WHERE user_id = last_insert_id();
END ELSE BEGIN
SELECT * FROM user WHERE email_id = #email_id;
END
END
I am trying to create user registration stored procedure in mysql but I am getting an error.
Query
CREATE PROCEDURE `test`.`sp_register`(fullname VARCHAR(50), Mob VARCHAR(10), Email VARCHAR(50), pass VARCHAR(255))
BEGIN
DECLARE s VARCHAR(20);
IF EXISTS(SELECT id FROM users WHERE email = Email)
THEN SET s = 'User already exists';
ELSE
INSERT INTO users(`name`,`mobile`,`email`,`password`,`created_at`)
VALUES(fullname,Mob, Email, pass,CURRENT_TIMESTAMP())
THEN SET s = "User Registered";
END IF;
END
You don't need a "THEN" statement in an ELSE block
IF EXISTS(SELECT id FROM users WHERE email = Email) THEN
SET s = 'User already exists';
ELSE
INSERT INTO users(`name`,`mobile`,`email`,`password`,`created_at`)
VALUES(fullname,Mob, Email, pass,CURRENT_TIMESTAMP())
SET s = "User Registered";
END IF;
https://dev.mysql.com/doc/refman/5.7/en/if.html
As Matthew answered, you don't need the "THEN".
You're also missing a semi-colon after the INSERT.
I have a stored routine that is meant to create a new desktop login token for my application, that verifies if the user has to relogin (anyway that's not important).
What is important is that the SQL I'm using doesn't seem to like me.
I only ever use T-SQL because I'm a .NET developer who focuses with SSMS for databases, but this time I stupidly decided to use MySQL with no experience XD
Here's the code:
CREATE PROCEDURE `insertNewToken`(IN `Username` VARCHAR(150), IN `Token` VARCHAR(500))
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
IF EXISTS(SELECT *
FROM desktopTokens
WHERE desktopTokens.AssignedUsername = Username) THEN
BEGIN
UPDATE desktopTokens
SET desktopTokens.TokenValue = Token
WHERE desktopTokens.AssignedUsername = Username
END
ELSE
BEGIN
INSERT INTO desktopTokens
VALUES
(Username, Token)
END
I keep getting errors at LINE 2 and LINE 15 but have no idea why!
NOTE: Token and Username are SP variables
Try:
DELIMITER $$
CREATE PROCEDURE `insertNewToken`(
IN `Username` VARCHAR(150),
IN `Token` VARCHAR(500)
)
BEGIN
IF EXISTS(SELECT *
FROM desktopTokens
WHERE desktopTokens.AssignedUsername = Username) THEN
UPDATE desktopTokens
SET desktopTokens.TokenValue = Token
WHERE desktopTokens.AssignedUsername = Username
;
ELSE
INSERT INTO desktopTokens
VALUES
(Username, Token)
;
END IF;
END $$
DELIMITER ;
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
I'm doing a table where I store the last time the users do login/logout. Just one row storing an Id, the action as a bit field and the moment as a DATETIME. My idea is to do a stored procedure to make an insert when the user is new and an update when the user exists. I've done this code:
DELIMITER $$
CREATE PROCEDURE sp_LastAction(in id_in int, accion_in bit)
begin
SELECT #CONT:= IdUsuario FROM login WHERE IdUsuario = id_in;
IF NOT #CONT then
INSERT INTO login(IdUsuario, Fecha, Accion)
values (id_in, NOW(), accion_in);
ELSE
UPDATE login SET Fecha = NOW(), Accion = accion_in
WHERE IdUsuario = id_in LIMIT 1;
end IF;
end$$
DELIMITER ;
But when I call the procedure it doesn't do anything, just returns the variable as a void field.
You can make a UPSERT.
CREATE PROCEDURE `sp_LastAction`(id_in int, accion_in bit)
BEGIN
INSERT INTO `login` (`idusuario`, `fecha`, `accion`) VALUES (id_in, now(), accion_in)
ON DUPLICATE KEY UPDATE `fecha` = now(), `accion` = accion_in;
END //
Here's an example: SQL Fiddle