I have the following query running against mysql:
DELIMITER $$
CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
PROCEDURE `mybook_store`.`myProc`()
/*LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'*/
BEGIN
DECLARE authId INT DEFAULT 0;
DECLARE
DECLARE CheckExists INT DEFAULT 0;
SET CheckExists = 0;
SELECT COUNT(*) INTO CheckExists FROM author WHERE fname = 'xxxx' AND surname='xxxx';
IF (CheckExists > 0) THEN
SELECT authorid INTO authId FROM author WHERE fname = 'xxxx' AND surname='xxxx';
ELSE
INSERT author(fname, surname) VALUES('xxxx', 'xxxx');
SET authId = LAST_INSERT_ID();
END IF;
END$$
DELIMITER ;
the above query will check if the inserted author exists in author table if not it will insert it if exist will not insert...
my questions:
i want to to get fname and surname if exists to variables then
insert in another query which insert into another table requires the
2 variables how to pass it to the query?
shall i use the authorid if exists then select fname and surname
that belong to authorid?
can i declare parameters instead of the actual value 'xxxx'?
thank you for your help
You're close, try this:
DELIMITER $$
CREATE PROCEDURE myProc (IN f_fname VARCHAR(25), IN f_surname VARCHAR(25))
BEGIN
DECLARE checkExists INT DEFAULT 0;
DECLARE authId INT DEFAULT 0;
SELECT COUNT(*) INTO checkExists FROM author WHERE fname = f_fname AND surname = f_surname;
IF(checkExists > 0) THEN
SELECT authorId into authId FROm author WHERE fname = f_fname AND surname = f_surname;
ELSE
INSERT INTO author(fname, surname) VALUES (f_fname, f_surname);
SET authId = LAST_INSERT_ID();
END IF;
END$$
DELIMITER ;
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
Why doesn't this MySQL function work with VARCHAR parameters? It works perfectly when parameter is removed
DELIMITER //
CREATE FUNCTION GETNAME(index varchar(30))
RETURNS varchar(50)
BEGIN
DECLARE fullname varchar(50);
SELECT name into fullname from roles where roles.id = (select role_id from user_role where user_role.user_id = (select id from users where users.index_nb = index)) ;
RETURN fullname;
END //
DELIMITER ;
In my user table the IDs user_id are randomly generated by the following functions:
DELIMITER #
CREATE FUNCTION GenerateRandomUserID()
RETURNS CHAR(15)
BEGIN
DECLARE user_id CHAR(15) DEFAULT '';
WHILE LENGTH(user_id) < 15 DO
SET user_id = CONCAT(user_id, SUBSTRING('0123456789', RAND() * 10 + 1, 1));
END WHILE;
RETURN user_id;
END#
DELIMITER ;
DELIMITER #
CREATE FUNCTION GenerateUniqueUserID()
RETURNS CHAR(15)
BEGIN
DECLARE user_id CHAR(15) DEFAULT '';
REPEAT
SET user_id = GenerateRandomUserID();
UNTIL NOT UserIDExists(user_id) END REPEAT;
RETURN user_id;
END#
DELIMITER ;
I then insert a user generating its ID with this function. So far so good. The problem is when I insert another user, which generates an infinite loop. I managed to boil down the problem to yet another function, UserIDExists, which always returns TRUE (it shouldn't, obviously).
DELIMITER #
CREATE FUNCTION UserIDExists(user_id CHAR(15))
RETURNS BOOL
BEGIN
RETURN EXISTS(SELECT 1 FROM `user` WHERE `user_id` = user_id);
END#
DELIMITER ;
This last function does not do what it's supposed to, but I can't figure out why. If a single user exists with any password this will return TRUE, only if there are no users does it return FALSE. Can anyone figure out why?
Update:
I also tried this. Same result:
DELIMITER #
CREATE PROCEDURE UserIDExists(IN user_id CHAR(15), OUT user_id_exists BOOL)
BEGIN
SET user_id_exists = 0;
SELECT 1 INTO user_id_exists FROM `user` WHERE `user_id` = user_id;
END#
DELIMITER ;
Update:
Tried this as well:
DELIMITER #
CREATE PROCEDURE UserIDExists(IN user_id CHAR(15), OUT user_id_exists BOOL)
BEGIN
IF ((SELECT `user_id` FROM `user` WHERE `user_id` = user_id) != NULL) THEN
SET user_id_exists = TRUE;
ELSE
SET user_id_exists = FALSE;
END IF;
END#
DELIMITER ;
Update:
I tried a few variantes with the following:
DELIMITER #
CREATE PROCEDURE UserIDExists_2(IN user_id CHAR(15), OUT user_id_exists CHAR)
BEGIN
SELECT `user_id` FROM `user` WHERE `user_id` = user_id;
END#
DELIMITER ;
And came to the conclusion that this returns 1 when user_id is also 1 and returns nothing for any other value. This is pretty odd, because this is the only row I have on the table:
# user_id, first_name, last_name, pwd, is_confirmed
'252316605573186', 'André', 'Fratelli', NULL, '0'
This is getting on my nerves...
This works. I though that the quotes where enough to distinguish the procedure's arguments from the table's columns, but I guess I was wrong.
DELIMITER #
CREATE PROCEDURE UserIDExists(IN p_user_id CHAR(15), OUT p_user_id_exists BOOL)
BEGIN
SET p_user_id_exists = EXISTS(SELECT `user_id` FROM `user` WHERE `user_id` = p_user_id);
END#
DELIMITER ;
MySQL 5.5
CREATE TABLE `card` (
`id` int,
`cardnumber` varchar(100),
`customer` varchar(100),
PRIMARY KEY (`id`)
);
INSERT INTO `card` VALUES (1, '5000', 'Google');
DELIMITER //
CREATE PROCEDURE `test` ()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE cardnumber varchar(20) DEFAULT "";
DECLARE cursor1 CURSOR FOR SELECT cardnumber FROM card WHERE customer = 'Google';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN cursor1;
get_card: LOOP
FETCH cursor1 INTO cardnumber;
IF finished = 1 THEN
LEAVE get_card;
END IF;
END LOOP get_card;
SELECT cardnumber;
CLOSE cursor1;
END //
DELIMITER ;
CALL test();
Returns no results, what did I do wrong?
There would be a ambiguity in identifying a column and a local variable if they are defined a same name. It IS always better practice to define a different naming convention in stored procedures, functions and trigger bodies when dealing with database object names like column.
To cross check, execute following procedure and see the result.
delimiter //
drop procedure if exists `same_name_test` //
create procedure `same_name_test`()
begin
DECLARE cardnumber varchar(20) DEFAULT "";
-- this statement will print empty string
SELECT cardnumber as cn
FROM card
WHERE customer = 'Google';
end;
//
delimiter ;
call `same_name_test`;
+------+
| cn |
+------+
| |
+------+
Modified Stored Procedure:
DELIMITER //
drop procedure if exists `test` //
CREATE PROCEDURE `test`()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE card_number varchar(20) DEFAULT "";
DECLARE cursor1 CURSOR FOR
SELECT cardnumber
FROM card_so_q23811277
WHERE customer = 'Google';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN cursor1;
get_card: LOOP
-- read cursor into new local variable
FETCH cursor1 INTO card_number;
IF finished = 1 THEN
LEAVE get_card;
END IF;
END LOOP get_card;
-- using new name of variable
SELECT card_number;
CLOSE cursor1;
END;
//
DELIMITER ;
Now call the Stored Procedure:
CALL `test`;
+-------------+
| card_number |
+-------------+
| 5000 |
+-------------+
I have the following function:
DROP FUNCTION IF EXISTS saveTableRow;
DELIMITER $$
CREATE FUNCTION saveTableRow(adapter_id int(10), view_id int(10),name varchar(255)) RETURNS TINYINT(1)
BEGIN
DECLARE retOK TINYINT DEFAULT 0;
IF (SELECT COUNT(*) FROM `tables` WHERE `adapter_id`=adapter_id AND `view_id`=view_id AND `name`=name ) = 0 THEN
INSERT INTO `tables` (`adapter_id`,`view_id`,`name`) VALUES (adapter_id, view_id, name);
SET retOK = 1;
END IF;
RETURN retOK;
END;
$$
DELIMITER ;
When i call the function to insert a new row with
SELECT saveTableRow(3,1,'Text');
I get the result '0' and there is no new row saved.
It might be a name collision problem. The name of the column is the same with the name of you parameter. You need to change the name of your parameter that is different from the name of your column. eg,
DROP FUNCTION IF EXISTS saveTableRow;
DELIMITER $$
CREATE FUNCTION saveTableRow(
_adapter_id int(10),
_view_id int(10),
_name varchar(255))
RETURNS TINYINT(1)
BEGIN
DECLARE retOK TINYINT DEFAULT 0;
IF (SELECT COUNT(*)
FROM `tables`
WHERE `adapter_id`=_adapter_id AND
`view_id`=_view_id AND
`name`=_name ) = 0 THEN
INSERT INTO `tables` (`adapter_id`,`view_id`,`name`)
VALUES (_adapter_id, _view_id, _name);
SET retOK = 1;
END IF;
RETURN retOK;
END;
$$
DELIMITER ;
change the if as follows as try please:
IF ((SELECT COUNT(*) FROM `tables` WHERE `adapter_id`=adapter_id AND `view_id`=view_id AND `name`=name ) < 1)