How to pass value for wherein in procedure of mysql - mysql

DELIMITER //
DROP PROCEDURE IF EXISTS salary_ref//# MySQL returned an empty result set (i.e. zero rows).
# MySQL returned an empty result set (i.e. zero rows).
CREATE PROCEDURE salary_ref(con int(11),IN id varchar(120),maxval int(11),minval int(11) , taxo int(11))
BEGIN
DECLARE s VARCHAR(50);
IF con = 1 THEN
SELECT `i` . * , `taxo`.`id` , `t`.`item_id` AS id, `u`.`name` AS user_name, `t`.`value` AS val
FROM (
`taxonomy` AS taxo
)
JOIN `item_taxo` AS t ON `t`.`taxo_id` = `taxo`.`id`
INNER JOIN `items` AS i ON `i`.`id` = `t`.`item_id`
INNER JOIN `users` AS u ON `u`.`id` = `i`.`created_by`
WHERE `t`.`value`
BETWEEN minval
AND maxval
AND `t`.`taxo_id` = taxo
AND `i`.`parent_tag_id` in (id);
ELSE
SELECT `i` . * , `taxo`.`id` , `t`.`item_id` AS id, `u`.`name` AS user_name, `t`.`value` AS val
FROM (
`taxonomy` AS taxo
)
JOIN `item_taxo` AS t ON `t`.`taxo_id` = `taxo`.`id`
INNER JOIN `items` AS i ON `i`.`id` = `t`.`item_id`
INNER JOIN `users` AS u ON `u`.`id` = `i`.`created_by`
WHERE `t`.`value`
BETWEEN minval
AND maxval
AND `t`.`taxo_id` = taxo
AND `i`.`parent_tag_id` in (id);
END IF;
END;
//# MySQL returned an empty result set (i.e. zero rows).
DELIMITER ;
//calling of that
call salary_ref(2,"\'36\',\'50\',\'57\'",17000000,0,7)
this is not work for me.

Following changes would solve the issues.
Change 1:
I suggest to not use same parameter names for stored procedure to represent column names of tables.
Unless you handle them properly there would arise an identifier conflict but does not seem to be there.
Change procedure signature as follows:
CREATE PROCEDURE salary_ref(
_con int(11), IN csv_id_values varchar(120),
_maxval int(11), _minval int(11), _taxo int(11)
)
Change 2:
You are trying to pass comma separated values for id field to use in where clause.
But using escape character won't solve your problem and that is not correct way of using input values.
call salary_ref( 2, '36,50,57', 17000000, 0, 7 )
The CSV value '36,50,57' can be used as is for where clause.
See the suggested Change below.
Change 3:
You can use FIND_IN_SET on CSV values instead of IN in the WHERE clause.
WHERE `t`.`value` BETWEEN _minval AND _maxval
AND `t`.`taxo_id` = _taxo
AND FIND_iN_SET( `i`.`parent_tag_id`, csv_id_values );
And, I think your procedure body is incomplete. Your IF con and ELSE are using the same SELECT statement. It is redundant, unless you change it.

Related

Error Code 1241 - Operand should contain 1 column(s)

I was creating a procedure and I came across this.
Does anyone know how to solve this?
delimiter $$
create procedure sp_cadastraAluno(
in nome varchar(150),
in chamada varchar(3),
in data date,
in ra varchar(12),
in turma varchar(50),
in cpf varchar(14))
begin
declare x int;
set x = (select * from tb_coordenador inner join tb_professor
on tb_coordenador.cd_coord = tb_professor.cd_coord
inner join prof_turma on
tb_professor.cd_prof = prof_turma.cd_prof
inner join tb_turma on
prof_turma.cd_turma = tb_turma.cd_turma
inner join tb_aluno on
tb_turma.cd_turma = tb_aluno.cd_turma where nm_turma = turma and tb_professor.cd_cpf = cpf);
insert into tb_aluno(nm_aluno, cd_chamada, dt_nascimento, cd_ra, cd_turma) values
(nome, chamada, data, ra, x);
end $$
I need to insert in tb_aluno and for this, I need to pull the code already inserted in tb_turma, but this error appears.
You can't set variable 'x' with multiple columns. try removing select * and replace with the column which you need.

Mysql procedure insert into temporary table

I have written a mysql procedure. I want into a temporary table using different select statement. While creating procedure its showing syntax error near at '
SELECT
value as last
FROM
wp_13_rg_lead
LEFT JOIN wp_13_rg_' at line 18
Below is my procedure
DELIMITER $$
CREATE PROCEDURE TEMP_JOIN_WORK ()
BEGIN
start transaction;
CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_JOIN(firstname varchar(500) not null,lastname varchar(500) not null) ;
insert into TEMP_JOIN(SELECT
value
FROM
wp_13_rg_lead
LEFT JOIN wp_13_rg_lead_detail on wp_13_rg_lead.id = wp_13_rg_lead_detail.lead_id
WHERE
wp_13_rg_lead.form_id = 9
AND CAST(wp_13_rg_lead_detail.field_number AS DECIMAL) = CAST(1.3 AS DECIMAL) ,
SELECT
value as lastname
FROM
wp_13_rg_lead
LEFT JOIN wp_13_rg_lead_detail on wp_13_rg_lead.id = wp_13_rg_lead_detail.lead_id
WHERE
wp_13_rg_lead.form_id = 9
AND CAST(wp_13_rg_lead_detail.field_number AS DECIMAL) = CAST(1.6 AS DECIMAL)
);
SELECT * FROM TEMP_JOIN;
commit;
END
$$
DELIMITER;
This should not give syntax error. In workbench, click on create stored procedure and copy the following between BEGIN END. Logic will work or not, that is a separate issue.
CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_JOIN(firstname VARCHAR(500) NOT NULL,lastname VARCHAR(500) NOT NULL) ;
INSERT INTO TEMP_JOIN VALUES((SELECT
`value`
FROM
wp_13_rg_lead
LEFT JOIN wp_13_rg_lead_detail ON wp_13_rg_lead.id = wp_13_rg_lead_detail.lead_id
WHERE
wp_13_rg_lead.form_id = 9
AND CAST(wp_13_rg_lead_detail.field_number AS DECIMAL) = CAST(1.3 AS DECIMAL)) , (
SELECT
`value` AS lastname
FROM
wp_13_rg_lead
LEFT JOIN wp_13_rg_lead_detail ON wp_13_rg_lead.id = wp_13_rg_lead_detail.lead_id
WHERE
wp_13_rg_lead.form_id = 9
AND CAST(wp_13_rg_lead_detail.field_number AS DECIMAL) = CAST(1.6 AS DECIMAL))
);
SELECT * FROM TEMP_JOIN;

MySQL procedure returning wrong value (INSERT SELECT confronting)

I'm completely new to MySQL, and have been bumping with some errors, but always I do find solutions, except for this one I can't understand how to get around it.
The following MySQL Procedure returns me a value if variable "ue" is 1 or 0 (a bunch of exists validation). The validation part (SET ue = EXISTS...) works without the rest of the code, as it should, the problem is not there. But when I do execute the command INSERT INTO SELECT, it does not work, it always return 0 as response, when it should be 1. These two lines are getting in confrontation with each other.
INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1;
SELECT ue AS response;
The procedure should add 'user id' and 'event id' into meetup_participation, and then update the row at 'users' corresponding to the user with that 'user id' to increment the 'events participated'. And it also UPDATE to increment the participation in the event with this 'event id'.
I am using the SET ue to validate things like, if user exists, if event does exists, if date of event is still valid, and if user is not already in this table. So I am passing this value as a boolean to INSERT INTO meetup_participation [...] WHERE ue = 1. After that, I do SELECT ue to inform validation returned true and procedure executed without problems.
Here is the full procedure.
CREATE DEFINER=`user`#`localhost` PROCEDURE `join_event`(IN `user_id` BIGINT(64), IN `event_id` INT) NOT DETERMINISTIC MODIFIES SQL DATA SQL SECURITY DEFINER
begin
DECLARE ue INT;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) AND EXISTS(SELECT 1 FROM meetup WHERE date > NOW() AND meet_id = event_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND participants <= max_participants) AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id);
INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1;
UPDATE users SET events_participated = events_participated + 1 WHERE fb_uid=user_id AND ue=1;
UPDATE meetup SET participants = participants + 1 WHERE meet_id=event_id AND ue=1;
SELECT ue AS response;
end
Thanks in advance.
The INSERT statement is executed separately from the SET ue =... statement. I'm not sure what you are trying to accomplish, but the code makes no sense.
If you want to add records to meetup_participation based on the EXISTS tests applied to each record in the users table, you would need to apply the tests to each record in your SELECT statement as part of the INSERT.
There are also numerous syntax/grammar issues in the code as shown.
If you could provide an explanation of what you are trying to accomplish with the procedure, that might allow someone to suggest the right way to code the procedure.
Selecting ue will not tell you if the procedure completed without error. You should research mysql transactions and mysql error handling. http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ is a good starting point.
You might end up with something like this
drop procedure if exists p;
delimiter //
CREATE DEFINER=`root`#`localhost` PROCEDURE `p`(
IN `inue` int,
IN `user_id` BIGINT(64),
IN `event_id` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''
begin
DECLARE ue INT;
declare exit handler for sqlexception
begin
rollback;
insert into errors (msg) select concat('error ' ,inue,',',user_id,',',event_id);
end;
set autocommit = 0;
#set ue = inue;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id)
AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id)
#AND EXISTS(SELECT 1 FROM meetup WHERE dt > NOW() AND meet_id = event_id)
AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND ifnull(participants,0) <= max_participants)
AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id)
;
select ue;
if ue = 1 then
start transaction;
INSERT INTO meetup_participation SELECT user_id, event_id,user_id, event_id;
UPDATE users SET events_participated = ifnull(events_participated,0) + 1 WHERE fb_uid=user_id = user_id;
UPDATE meetup SET participants = ifnull(participants,0) + 1 WHERE meet_id = event_id ;
commit;
end if;
SELECT ue AS response;
end //
The error table looks like this
CREATE TABLE `errors` (
`msg` varchar(2000) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
Note I am not suggesting this is a solution appropriate to your site , you need to do the research and figure out what is best for you.

MySQL procedure for searching a table with multiple parameters in multiple columns

I am new to MySQL Procedures and I am trying to write a search procedure for a table.
CREATE PROCEDURE `Search`(
IN in_locality VARCHAR(200),
IN in_type VARCHAR(200),
IN in_city VARCHAR(200)
)
BEGIN
SELECT * FROM property_details MRP INNER JOIN property_image MRPI
ON MRP.basic_id=MRPI.basic_id
WHERE ((in_locality = '') or (MRP.locality = in_locality))
AND ((in_property_type = '') or (MRP.property_type = in_property_type))
AND ((in_city = '') or (MRP.city = in_city))
GROUP BY MRP.id;
END
Now this procedure is working for:
CALL Search('','','','mumbai');
but not for:
CALL Search('','',''mumbai','pune'');
In normal SQL I could use this query for that:
SELECT * FROM property_details where city in('mumbai','chennai')
But I don't how to do this in a procedure.
Your CALL examples have got 4 arguments, while your CREATE PROCEDURE statement has only got 3. This is because you are trying to specify multiple cities. For this you can use the FIND_IN_SET function to specify the input parameters as comma-seperated lists (MySQL Docs for FIND_IN_SET)
Instead try this
CREATE PROCEDURE `Search`(
IN in_locality VARCHAR(255),
IN in_type VARCHAR(255),
IN in_city VARCHAR(255)
)
BEGIN
SELECT
*
FROM property_details MRP INNER JOIN property_image MRPI
ON MRP.basic_id=MRPI.basic_id
WHERE ( in_locality = '' XOR FIND_IN_SET( MRP.locality , in_locality ) )
AND ( in_property_type = '' XOR FIND_IN_SET( MRP.property_type , in_property_type ) )
AND ( in_city = '' XOR FIND_IN_SET( MRP.city , in_city ) )
GROUP BY MRP.id;
END
You can then call this using strings with comma-seperated lists in such as the following examples. I also changed them to XOR's because you don't want it searching for an empty string, and changed all 3 searches to be FIND_IN_SET searches.
CALL Search('','','','mumbai');
CALL Search('','','mumbai,pune');

Loop through table variable and insert missing rows into new table variable

I have a table variable which is populated with a number of rows. What I am trying to achieve, is to loop through each row of the table variable, see if the ID column exists in another standard table and add that row to a newly created table variable.
My code is as follows:
DECLARE
#Intervention_ID int
SET #Intervention_ID = 969
/*---Check if intervention has pre-requisites---*/
DECLARE #PreRequisites TABLE
(
[Intervention_ID] int
)
INSERT INTO #PreRequisites
(
[Intervention_ID]
)
SELECT IP.[Requisite_ID]
FROM DI_Intervention_Prerequisites IP
WHERE
IP.[Intervention_ID] = #Intervention_ID
AND IP.[Prerequisite] = 1
/*---Check if pre-requisites have been completed---*/
DECLARE #Result TABLE
(
[Type_ID] int
, [Type_Name] nvarchar(max)
, [Intervention_ID] int
, [Intervention_Name] nvarchar(max)
)
WHILE NOT EXISTS
(
SELECT TOP 1 1
FROM DI_Employee_Intervention EI
WHERE
EI.[Intervention_ID] = (SELECT [Intervention_ID] FROM #PreRequisites)
)
INSERT INTO #Result
(
[Type_ID]
, [Type_Name]
, [Intervention_ID]
, [Intervention_Name]
)
As you can see, I am stuck at the WHILE NOT EXISTS part of the code. What needs to happen is for each row within #PreRequisites that does not exist in DI_Employee_Intervention, that specific #PreRequisites row need to be inserted into #Result.
Why don't you just use a set-based approach instead of the RBAR (row-by-agonizing-row) procedural approach you have now??
Something like:
INSERT INTO #Result([Type_ID], [Type_Name], [Intervention_ID], [Intervention_Name])
SELECT
... (some columns to match the columns of #Result)......
FROM
dbo.DI_Intervention_Prerequisites IP
WHERE
IP.[Intervention_ID] = #Intervention_ID
AND IP.[Prerequisite] = 1
AND NOT EXISTS (SELECT *
FROM DI_Employee_Intervention EI
WHERE EI.[Intervention_ID] = IP.[Intervention_ID] )
or something like that (I didn't quite understand all your intermediate steps and why you take them....)