How to write multiple queries in stored procedure - php

What I'm trying to do is when user roles changed to 1 or from 1 then delete all his entries from ForumManager table which IsDirect value is 0 or if its value changes to 1 then I need to insert person's entry to ForumManager table for all ForumID.
But for inserting it I have to run 1 more queries to get ForumID and insert in ForumManager with loop.
What I try till now is incomplete and maybe not correct or right way I don't know how to run loop inside stored procedure.
delimiter //
CREATE PROCEDURE update_forum_admin (IN user_id INT, IN previous_role INT,IN new_role INT)
BEGIN
if(previous_role == 1)
{
DELETE ForumManager WHERE UserID=user_id AND IsDirect=0
}
elseif(new_role == 1)
{
SELECT ForumID FROM Forum
INSERT ForumManager (ForumID,UserID,IsDirect) VALUES (forum_id,user_id,0)
}
END//
delimiter ;

If you have a column name user_id in Forum table than rename the parameter from user_id to userId.
delimiter //
CREATE PROCEDURE update_forum_admin (IN userId INT, IN previous_role INT,IN new_role INT)
BEGIN
if(previous_role == 1)
{
DELETE ForumManager WHERE UserID=userId AND IsDirect=0
}
elseif(new_role == 1)
{
INSERT ForumManager (ForumID, UserID, IsDirect)
SELECT ForumID, userId, 0 FROM Forum group by ForumID, userId, 0
}
END//
delimiter ;

You can declare a coursor with ID_forum and iterate it inside an elseif statement like below(is a pseudo code, if you have e problem to implement it let me know):
CREATE PROCEDURE update_forum_admin (IN user_id INT, IN previous_role INT,IN new_role INT)
BEGIN
CURSOR CUR_ID_FORUM
IS
SELECT ForumID FROM Forum;
if(previous_role == 1)
{
DELETE ForumManager WHERE UserID=user_id AND IsDirect=0
}
elseif(new_role == 1)
{
FOR REC_ID_FORUM IN CUR_ID_FORUM
LOOP
INSERT ForumManager (ForumID,UserID,IsDirect) VALUES (REC_ID_FORUM,user_id,0)
END LOOP;
}
END update_forum_admin ;

its quiet late but Mohit you can get rid of syntax error by modifying code like
CREATE PROCEDURE update_forum_admin (IN user_id INT, IN previous_role INT,IN new_role INT)
BEGIN
if(previous_role = 1)
BEGIN
DELETE ForumManager WHERE UserID=user_id AND IsDirect=0
END
if(new_role = 1)
BEGIN
SELECT ForumID FROM Forum
INSERT ForumManager (ForumID,UserID,IsDirect) VALUES (forum_id,user_id,0)
END
Also I Can see when you delete a user from ForumManager you do not delete for particular Forum. May be you have only one Forum and if that is the case then take top 1 Forum Id from Forum table

Related

Unable to create mysql trigger from php

How do I use php and mysql to create the following trigger for each table created.
I want to convert the following code to be used as a sql query from php.
DELIMITER $$
CREATE TRIGGER trigger1
BEFORE INSERT
ON table1
FOR EACH ROW
BEGIN
SELECT COUNT(*) INTO #cnt FROM table1;
IF #cnt >= 25 THEN
CALL sth();
END IF;
END
$$
DELIMITER ;
I tried to use the following but it does not work.
if ($method == "T")// method is activated if $_GET["method'] = T method is set to T in script to allways return true
{
$sql = "CREATE TRIGGER TRIGGER1
BEFORE INSERT
ON 49a64d6512
FOR EACH ROW
BEGIN
SELECT COUNT(*) INTO #cnt FROM 49a64d6512;
IF #cnt >=25 THEN
CALL sth();
END IF;
END";
echo '1';
}
Is what i am trying to do even possible?

calling mysql procedure using codeigniter [Error: result consisted more than one row]

I have table status and status_stage . After insert in status table, I want to add it to the status_stage table. I have this procedure:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `addStatus`(status VARCHAR(45), stage int (8))
BEGIN
DECLARE status_id INT DEFAULT NULL;
INSERT INTO status (status)
VALUES (status);
SELECT id INTO status_id FROM status WHERE status = status;
INSERT INTO stage_status (stage,status)
VALUES (stage,id);
END
And I call that function with this:
$result= $this->db->query("call addStatus('$status', $stage)");
return ($result->num_rows()>0);
When I tried it it gives me this Error:
Result consisted of more than one row
Your SELECT ... INTO statement got more than one result because of your WHERE clause with status = status, this equals forever
you need to change the param name to distinguish it from the table column name (eg. status_param)

Multiple IF in Mysql Trigger is not working

I'm trying to log changes of a table into another table. But my trigger is not working. Need help:
// Mysql code below
create trigger upd_stu_info
before update
on kisalg_student
for each row
begin
IF OLD.stu_name != NEW.stu_name
THEN
INSERT INTO `kisalg_logactions`
(adm_no, change_type,change_head, old_value,new_value,user,date_time,session)
VALUES
(NEW.adm_no, 'stu_info','Change In Student Name ', OLD.stu_name, NEW.stu_name, NEW.user, NEW.date_time, NEW.session);
END IF;
IF OLD.fat_name != NEW.fat_name
THEN
INSERT INTO `kisalg_logactions`
(adm_no, change_type, change_head, old_value, new_value, user, date_time, session)
VALUES
(NEW.adm_no, 'stu_info','Change In Father Name ', OLD.fat_name, NEW.fat_name, NEW.user, NEW.date_time, NEW.session);
END IF;
end;
I just tried the trigger on mysql and using the following I did not get any syntax error
delimiter //
create trigger upd_stu_info
before update
on kisalg_student
for each row
begin
IF OLD.stu_name != NEW.stu_name
THEN
INSERT INTO `kisalg_logactions`
(adm_no, change_type,change_head, old_value,new_value,user,date_time,session)
VALUES
(NEW.adm_no, 'stu_info','Change In Student Name ', OLD.stu_name, NEW.stu_name, NEW.user, NEW.date_time, NEW.session);
END IF;
IF OLD.fat_name != NEW.fat_name
THEN
INSERT INTO `kisalg_logactions`
(adm_no, change_type, change_head, old_value, new_value, `user`, date_time, session)
VALUES
(NEW.adm_no, 'stu_info','Change In Father Name ', OLD.fat_name, NEW.fat_name, NEW.`user`, NEW.date_time, NEW.session);
END IF;
end; //

MySql error : Result consisted of more than one row

I have the error : Result consisted of more than one row but i can't find out it.
The entry id_user has only one record in its table.
The procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `delete_user_deep`(id_user int(11))
BEGIN
declare nome_loc varchar(45);
declare cognome_loc varchar(45);
select nome,cognome
into nome_loc,cognome_loc
from user
where id_user=id_user;
delete from Radius.radcheck where username in (
select mac_address from machine where id_user =id_user);
delete from Radius.radreply where username in (
select mac_address from machine where id_user =id_user);
delete from machine_ip where id_machine in (
select id_machine from machine where id_user=id_user);
delete from machine where id_user = id_user;
delete from document where id_user=id_user;
delete from user where id_user=id_user;
insert into log_generic values(
NULL,
'USER',
'Delete User Deep',
(select concat ('User: ',id_user,' Name: ',cognome_loc,' Prename: ',nome_loc)),
now());
END
The problem is in this statement:
select nome,cognome
into nome_loc,cognome_loc
from user
where id_user=id_user;
This will return an error if there is more than one row. The error is documented here.
This is caused because the parameter name is the same as the column name. The id_user is referring to the column on both sides of the comparison.
The query should look like:
select nome, cognome
into nome_loc, cognome_loc
from user
where id_user = param_id_user;
Always prefix parameter and variable names with something to distinguish them from column names.

How to optimise this temporary table query?

I have written a stored procedure that takes comma separated value as input and another value. I traverse values from comma separated value and then run a query for each value. now I need to return result so I thought to store results in temporary table and then selected values from that temporary table.But it is taking too long.
for query with 163 comma separated values it is taking 7 seconds.
for query with 295 comma separated values it is taking 12 seconds.
Here is procedure:-
DELIMITER $
create procedure check_fbid_exists(IN myArrayOfValue TEXT, IN leaderID INT(11) )
BEGIN
DECLARE status TINYINT(1);
DECLARE value INT(11);
DECLARE pos int(11);
CREATE TEMPORARY TABLE fbid_exists_result (userID int(11), status tinyint(1));
WHILE (CHAR_LENGTH(myArrayOfValue) > 0)
DO
SET pos=LOCATE( ',', myArrayOfValue);
IF pos>0 THEN
SET value = LEFT( myArrayOfValue,pos-1 );
SET myArrayOfValue= SUBSTRING( myArrayOfValue,pos+1 );
ELSE
SET value = myArrayOfValue;
SET myArrayOfValue='';
END IF;
SELECT EXISTS(SELECT 1 FROM users_followings WHERE UserID=value and LeaderUserID=leaderID LIMIT 1) INTO status;
insert into fbid_exists_result VALUES(value,status);
END WHILE;
SELECT * FROM fbid_exists_result ;
DROP TEMPORARY TABLE IF EXISTS fbid_exists_result ;
END$

Categories