Cursor in mysql stored procedure executes only 1 iteration - mysql

I have been struck in this stored procedure for 2 days now.
Here's the code
BEGIN
DECLARE in_township_id INT DEFAULT 2;
DECLARE in_billing_month INT DEFAULT 1;
DECLARE in_billing_month_string VARCHAR(15) DEFAULT 'January';
DECLARE in_billing_year INT DEFAULT 2016;
DECLARE in_account_id INT DEFAULT 1;
DECLARE out_status INT DEFAULT 0;
DECLARE in_invoice_date DATETIME DEFAULT CURRENT_DATE();
DECLARE _no_flats INT;
DECLARE _current_month_data_exists INT;
DECLARE _flat_id INT;
DECLARE _current_billing_month, _current_billing_year INT;
DECLARE _next_billing_month, _next_billing_year INT;
DECLARE _current_balance, _new_balance FLOAT DEFAULT 0;
DECLARE _maintenance, _power_backup, _service_tax, _penalty FLOAT DEFAULT 0;
DECLARE _maintenance_price, _power_backup_price, _service_tax_price, _balance_price, _penalty_price FLOAT DEFAULT 0;
DECLARE _consumed_units INT;
DECLARE _penal_interest_remark, _maintenance_bill_remark, _power_backup_remark, _service_tax_remark, _maintenance_account_remark VARCHAR(100);
DECLARE _total_penalty, _total_maintenance, _total_power_backup, _total_service_tax FLOAT DEFAULT 0;
DECLARE _all_flats_cursor CURSOR FOR SELECT id FROM flat_resident_v WHERE township_id=2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET _no_flats=1;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SET out_status=2;
SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated';
END;
START TRANSACTION;
SET _current_billing_month=in_billing_month;
SET _current_billing_year=in_billing_year;
SET _next_billing_month=in_billing_month;
SET _next_billing_year=in_billing_year;
IF in_billing_month=1 THEN
SET _current_billing_month=12;
SET _current_billing_year=in_billing_year-1;
END IF;
IF in_billing_month=12 THEN
SET _next_billing_month=1;
SET _next_billing_year=in_billing_year+1;
ELSE
SET _next_billing_month = in_billing_month+1;
END IF;
SELECT CONCAT('On account of billing month ', in_billing_month_string) INTO _maintenance_account_remark;
SELECT penalty, rate_maintenance, rate_power_backup, service_tax_rate
INTO _penalty, _maintenance, _power_backup, _service_tax FROM account_master WHERE id=in_account_id;
SELECT CONCAT('Charged # ', _penalty*1200, '%') INTO _penal_interest_remark;
SELECT CONCAT('Charged # Rs. ', _maintenance, '/sq. feet') INTO _maintenance_bill_remark;
SELECT CONCAT('Charged # Rs. ', _power_backup, '/unit') INTO _power_backup_remark;
SELECT CONCAT('Charged # ', _service_tax_price*100, '%') INTO _service_tax_remark;
SET out_status = 0;
INSERT INTO temp(value1, value2) VALUES('SUCCESS', 'Initialization Completed');
OPEN _all_flats_cursor;
SET _no_flats=0;
ALL_FLATS_LOOP: LOOP
FETCH _all_flats_cursor INTO _flat_id;
IF _no_flats=1 THEN
INSERT INTO temp(value1, value2) VALUES('LOOP BREAK', _no_flats);
LEAVE ALL_FLATS_LOOP;
END IF;
IF _no_flats=0 THEN
INSERT INTO temp(value1, value2) VALUES('INSIDE LOOP', _no_flats);
INSERT INTO temp(value1, value2) VALUES('FLAT_ID', _flat_id);
SELECT count(FLATS.id) INTO _current_month_data_exists FROM account_flat_ledger as FLATS
WHERE FLATS.flat_id=_flat_id AND FLATS.debit_month=in_billing_month
AND FLATS.debit_year=in_billing_year FOR UPDATE;
IF _current_month_data_exists=0 THEN
SET out_status = 1;
INSERT INTO temp(value1, value2) VALUES('_current_month_data_exists', 'FAILED: Data not exists for billing year');
LEAVE ALL_FLATS_LOOP;
END IF;
SELECT consumed_units INTO _consumed_units FROM account_power_backup_usage
WHERE flat_id=_flat_id AND month=in_billing_month AND year=in_billing_year;
INSERT INTO temp(value1, value2) VALUES('SUCCESS', 'Power Ok');
SELECT balance INTO _current_balance FROM account_flat_ledger as FLATS
WHERE FLATS.flat_id=_flat_id AND FLATS.debit_month=_current_billing_month AND FLATS.debit_year=_current_billing_year FOR UPDATE;
IF _current_balance>0 THEN
SET _penalty_price = _penalty*_current_balance;
END IF;
SET _maintenance_price = _maintenance*1000;
SET _power_backup_price = _power_backup*_consumed_units;
SET _service_tax_price = _service_tax * (_maintenance+_power_backup);
SET _new_balance = _current_balance + _penalty + _maintenance + _power_backup + _service_tax;
INSERT INTO temp(value1, value2) VALUES('SUCCESS', 'All Values Set');
UPDATE account_flat_ledger SET penal_interest=_penalty_price, maintenance_bill=_maintenance_price, service_tax=_service_tax_price,
power_backup=_power_backup_price, opening_balance=_current_balance,received_amount=0, balance=_new_balance,
debit_date=CURDATE(), penal_interest_remark=_penal_interest_remark, maintenance_bill_remark=_maintenance_bill_remark,
power_backup_remark=_power_backup_remark, service_tax_remark=_service_tax_remark
WHERE flat_id=_flat_id AND debit_month=in_billing_month AND debit_year=in_billing_year;
INSERT INTO account_flat_ledger(flat_id, debit_month, debit_year)
VALUES(_flat_id, _next_billing_month, _next_billing_year);
INSERT INTO temp(value1, value2) VALUES('SUCCESS', 'Insertion of new Flats OK');
SET _total_maintenance = _total_maintenance + (_maintenance_price
+ _power_backup_price + _service_tax_price + _penalty_price);
SET _total_penalty = _total_penalty + _penalty_price;
SET _total_power_backup = _total_power_backup + _power_backup_price;
SET _total_service_tax = _total_service_tax + _service_tax_price;
INSERT INTO temp(value1, value2) VALUES('SUCCESS', 'Flat over');
END IF;
END LOOP ;
CLOSE _all_flats_cursor;
IF out_status != 0 THEN
ROLLBACK;
END IF;
SELECT #out_status;
END IF;
COMMIT;
END
Previously I have done this whole thing using Java code (using ResultSets and PreparedStatements). But someone told me to use stored procedure for this purpose to make things handy and efficient.
Problem: The loop i.e. Cursor executes only ones, but there are 3 records present in the table.
I used logging into temp table to trace the error but couldn't find.

Related

MySQL If Statement and Increment

I am having issues with a MySQL If statement that creates a group rank. here is the MySQL Statement:
SELECT EnCode, EnName, QuScore,
#scorerank := IF(#currathlete = EnCode, #scorerank + 1, 1),
#currathlete := EnCode
FROM ranking ORDER BY EnCode, QuScore DESC
It currently gives the following output
'1004277','Ashe','1628','1','1004277'
'1004277','Ashe','1309','1','1004277'
'1004277','Ashe','1263','1','1004277'
'1004277','Ashe','648','1','1004277'
'1004277','Ashe','645','1','1004277'
'1004277','Ashe','1628','1','1004277'
'1015934', 'Sabina', '544', '1', '1015934'
'1015934', 'Sabina', '455', '1', '1015934'
'1015934', 'Sabina', '276', '1', '1015934'
'1015934', 'Sabina', '216', '1', '1015934'
What it should be doing is incrementing each of the '1' numbers by one for each row that has the same code, and then starting from 1 again when it sees a different code number (1004277, then 1015934 in this case)
Any help is appreciated as i have followed a number of examples online using the above method but seem to hit the same issue a this point.
Try this way in stored Procedure:
drop PROCEDURE if EXISTS INCREMENTME;
create PROCEDURE INCREMENTME()
BEGIN
DECLARE OldEnNamevar VARCHAR(10) DEFAULT NULL;
DECLARE done INT DEFAULT FALSE;
DECLARE Encodevar VARCHAR(10);
DECLARE EnNamevar VARCHAR(10);
DECLARE QuScorevar VARCHAR(10);
DECLARE scorerankvar VARCHAR(10);
DECLARE currathalthletevar VARCHAR(10);
DECLARE countcode int(29) DEFAULT(1);
DECLARE counter int(20) default 0;
DECLARE get_cur CURSOR FOR select `Encode`,`EnName`,`QuScore`,`scorerank`,`currathalthlete` from tbl_ranking;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
drop table if exists temp_temptable;
create TEMPORARY table temp_temptable(Encodevar VARCHAR(50) NULL,EnNamevar VARCHAR(50) NULL,QuScorevar VARCHAR(50) NULL,scorerankvar VARCHAR(50) NULL,currathalthletevar VARCHAR(50) NULL,recordCount int(10) null);
OPEN get_cur;
REPEAT
set counter = counter + 1;
FETCH get_cur INTO Encodevar,EnNamevar,QuScorevar,scorerankvar,currathalthletevar;
if (OldEnNamevar = EnNamevar) THEN
set countcode = countcode +1;
ELSE
if(counter=1) then
set countcode = 1;
ELSE
set countcode = 0;
end if;
end if;
if (OldEnNamevar != EnNamevar) THEN
set countcode = 1;
end if;
if(OldEnNamevar=NULL) then
set countcode = 1;
end if;
insert into temp_temptable (Encodevar,EnNamevar,QuScorevar,scorerankvar,currathalthletevar,recordCount) values(Encodevar,EnNamevar,QuScorevar,scorerankvar,currathalthletevar,countcode);
set OldEnNamevar = EnNamevar;
UNTIL done END REPEAT;
select * from temp_temptable;
drop temporary table if exists temp_temptable;
CLOSE get_cur;
END
call the procedure like this:
call INCREMENTME();
Here's the result:
You have to initialize your variables, otherwise they are null (at least at the beginning of the session, probably not anymore if you run it twice), and your query will give strange results. Try
SELECT EnCode, EnName, QuScore,
#scorerank := IF(#currathlete = EnCode, #scorerank + 1, 1),
#currathlete := EnCode
FROM ranking, (select #currathlete := '', #scorerank := 0) init
ORDER BY EnCode, QuScore DESC

Calling a Stored Procedure properly in MySQL

Here's my Stored Procedure:
DELIMITER //
CREATE PROCEDURE facturar(codigo int(6),fecha date,cedula VARCHAR(9),cantidad int(3),peso VARCHAR(10),precio varchar(10))
BEGIN
DECLARE P float;
Declare total float;
set P=0;
set total=0;
insert into factura VALUES(ID,fecha,cedula,cantidad, peso, `precio`);
set P=peso*4;
if P between 2000 and 10000 then SET precio= (P*0.05)+(P*0.12)+P;
elseif P > 10000 then set precio= (P*0.05)+(P*0.10)+(P*0.12)+P;
else set precio= (P*0.12)+P;
end if;
set total = precio;
select concat("Total de envio=", total);
END;
//
When i make the call:
call facturar (NULL,'2016/01/13', 'v18834415', '2', '96400', '');
It shows the result:
Total de envió=489712
But, once I take a look at the table the "precio" is in white while the other values are filled.
You are setting precio as a column in the insert. Then you do some calculations, and never do anything with the values.
I strongly encourage two of things:
indicate the difference between variables and columns by using a prefix for variables
list all columns for insert
In your case, I think you need to move the insert after you set precio:
CREATE PROCEDURE facturar(
in_codigo int(6),
in_fecha date,
in_cedula VARCHAR(9),
in_cantidad int(3),
in_peso VARCHAR(10),
in_precio varchar(10)
)
BEGIN
DECLARE #P float;
Declare #total float;
set #P = 0;
set #total = 0;
set #P = in_peso*4;
if #P between 2000 and 10000 then SET in_precio= (#P*0.05)+(#P*0.12)+#P;
elseif #P > 10000 then set in_precio= (#P*0.05)+(#P*0.10)+(#P*0.12)+#P;
else set in_precio = (#P*0.12)+#P;
end if;
set #total = in_precio;
insert into factura( . . . )
VALUES(in_ID, in_fecha, in_cedula, in_cantidad, in_peso, in_precio);
select concat('Total de envio=', #total);
END;
You need to execute insert query after setting the value.
DELIMITER //
CREATE PROCEDURE facturar(codigo int(6),fecha date,cedula VARCHAR(9),cantidad int(3),peso VARCHAR(10),precio varchar(10))
BEGIN
DECLARE P float;
Declare total float;
set P=0;
set total=0;
set P=peso*4;
if P between 2000 and 10000 then SET precio= (P*0.05)+(P*0.12)+P;
elseif P > 10000 then set precio= (P*0.05)+(P*0.10)+(P*0.12)+P;
else set precio= (P*0.12)+P;
end if;
set total = precio;
select concat("Total de envio=", total);
insert into factura VALUES(ID,fecha,cedula,cantidad, peso, total);
END;
//
use total variable in insert query instead of backquoted value

Mysql stored procedure skipping inserts

I have a procedure that I have developed and well tested. Now that it has been deployed commercially , it fails to insert some records but still returns expected results. No errors or warnings are thrown.
It can miss 3 inserts per 150 calls.
What could I be missing.
MySQL is continue to execute your query until any error occurs. But after error if they are have correct statement continue to execute. I think within the errors skips the three records.
The thing is, its being called by a java service which captures any mysql error thrown but it does no throw one. Not even a warning.
Here is the code:
DELIMITER $$
USE `parkinglot`$$
DROP PROCEDURE IF EXISTS `process_acard`$$
CREATE DEFINER=`jeremiah`#`localhost` PROCEDURE `process_acard`(_station INT(4),_cardno VARCHAR(10),_baloncard DOUBLE,_transam FLOAT,_lane VARCHAR(50),_lpn VARCHAR(8),_vehcat INT(4),_fimagepath VARCHAR(100))
BEGIN
DECLARE bool_code VARCHAR(6);
DECLARE error_code VARCHAR(6);
DECLARE info_msg VARCHAR(6);
DECLARE message_string VARCHAR(255);
DECLARE return_value FLOAT DEFAULT 0;
DECLARE master_or_blocked INTEGER(2);
DECLARE is_blacklisted INT(2);
DECLARE stn_name VARCHAR(50);
DECLARE stn_type VARCHAR(20);
DECLARE mysite VARCHAR (4);
DECLARE myzone INTEGER (4);
DECLARE entry_zone INTEGER (4);
DECLARE merch_agent VARCHAR(11);
DECLARE sea_reg_lpn INTEGER(2) DEFAULT 0;
DECLARE sea_ent_lpn INTEGER(2) DEFAULT 0;
DECLARE sea_lpn VARCHAR(10);
DECLARE ent_lpn VARCHAR(10);
DECLARE sea_validfrom DATETIME;
DECLARE sea_validto DATETIME;
DECLARE op_date DATE;
DECLARE sea_block_status INT(2);
DECLARE sea_exists INT(10);
DECLARE tea_exists INT(10);
DECLARE location INT(4);
DECLARE ta_rif INT(4);
DECLARE ent_device VARCHAR(50);
DECLARE error_sev VARCHAR(50);
DECLARE _limagepath VARCHAR(50);
DECLARE time_in DATETIME;
DECLARE time_now DATETIME;
DECLARE raw_duration TINYINT;
DECLARE days_spent TINYINT DEFAULT 0;
DECLARE fd_fee FLOAT DEFAULT 0;
DECLARE fee1 FLOAT DEFAULT 0;
DECLARE fee2 FLOAT DEFAULT 0;
DECLARE dow1 TINYINT;
DECLARE dow2 TINYINT;
DECLARE total_fee FLOAT;
DECLARE cardrec INT;
DECLARE shift_string VARCHAR(100);
DECLARE myshift VARCHAR(100);
DECLARE pass_key VARCHAR(5);
DECLARE amount_charged DOUBLE;
DECLARE pay_state INT(4);
DECLARE lipa_activity INT(4);
DECLARE ent_dex VARCHAR(200);
DECLARE exit_dex VARCHAR(200);
DECLARE acq_entry_dex VARCHAR(200);
DECLARE acq_trans_dex VARCHAR(200);
DECLARE pending_value INTEGER(10);
DECLARE pending INT(1) DEFAULT 0;
DECLARE pending_id INT(10) UNSIGNED;
DECLARE use_entry_zone INT;
DECLARE sarit_apb INT(1);
DECLARE char_amount VARCHAR(100);
DECLARE useful_transtype INT(1);
DECLARE sarit_avg_amt DOUBLE DEFAULT 0;
DECLARE card_trans_type INT(2);
DECLARE confirm_insert INT(2);
DECLARE newest_record_id INT(8);
DECLARE event VARCHAR(50) DEFAULT '';
DECLARE story VARCHAR(100) DEFAULT '';
DECLARE lastinsert BIGINT;
DECLARE check_entry_bal INT(1);
DECLARE min_entry_bal INT(8);
IF(CHAR_LENGTH(_cardno)<9 OR CHAR_LENGTH(_station)<1)THEN
SET bool_code='FALSE';
SET error_code='ER225';
SET info_msg='MS225';
ELSE
IF (ISNULL(_vehcat) OR CHAR_LENGTH(_vehcat)<1) THEN SET _vehcat=1; END IF;
SELECT get_lpn_path(_lpn,NOW()) INTO _limagepath;
SELECT station_name,station_type,site_no,site_zone,commercial_id FROM site_config
WHERE station_id=_station INTO stn_name,stn_type,mysite,myzone,merch_agent;
INSERT INTO acard_temp_log(`card_no`,`card_event`) VALUES(_cardno,stn_type);/*Tell the real story*/
SELECT card_status FROM special_acards WHERE card_no=_cardno LIMIT 1 INTO master_or_blocked;/*1-master,2-blocked*/
IF(master_or_blocked=2)THEN
SET event='SPECIAL';
INSERT INTO bbc_attempts(`card_no`,`trans_date`,`station_name`,`lane_name`,`stationid`)VALUES
(_cardno,NOW(),stn_name,_lane,_station);
SET bool_code='FALSE';
SET error_code='ER244';
SET info_msg='MS244';
ELSEIF(master_or_blocked=1)THEN
SET event='SPECIAL';
INSERT INTO mastercard_transactions(`card_no`,`trans_date`,`station_name`,`lane_name`,`stationid`)VALUES
(_cardno,NOW(),stn_name,_lane,_station);
SET bool_code='TRUE';
SET error_code='ER000';
SET info_msg='MS245';
ELSE
/*we continue after realising card is neither blocked nor a mastercard.Now we check if it is globally blacklisted */
SELECT blocked FROM acard_blacklist WHERE card_no=_cardno LIMIT 1 INTO is_blacklisted;
IF(is_blacklisted=1)THEN
SET event='SPECIAL';
INSERT INTO bbc_attempts(`card_no`,`trans_date`,`station_name`,`lane_name`,`stationid`)VALUES
(_cardno,NOW(),stn_name,_lane,_station);
SET bool_code='FALSE';
SET error_code='ER229';
SET info_msg='MS229';
ELSE
/*mhh.Not blacklist. Lets now check if it is a seasonal card with all checks*/
SELECT `s_id`,`validfrom`,`validto`,`blocked`,car_reg FROM seasonal_cards WHERE card_no=_cardno AND site_no=mysite INTO sea_exists,sea_validfrom,sea_validto,sea_block_status,sea_lpn ;
IF(sea_exists>=1)THEN/*this is a seasonlacard*/
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='seasonal_LPNI' AND site_applicable=mysite INTO sea_ent_lpn;
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='seasonal_reg_LPNI' AND site_applicable=mysite INTO sea_reg_lpn;
IF(sea_block_status=1)THEN/*check if card is blocked by seasonal card manager*/
SET event='SPECIAL';
INSERT INTO bsc_attempts(`card_no`,`trans_date`,`station_name`,`lane_name`,`stationid`,bsc_description)VALUES
(_cardno,NOW(),stn_name,_lane,_station,'BLOCKED');
SET bool_code='FALSE';
SET error_code='ER244';
SET info_msg='MS246';
ELSE/*card not blocked by seasonal card manager*/
IF(NOW() > sea_validto)THEN/*is this card expired*/
INSERT INTO bsc_attempts(`card_no`,`trans_date`,`station_name`,`lane_name`,`stationid`,bsc_description)VALUES
(_cardno,NOW(),stn_name,_lane,_station,'EXPIRED');
SET bool_code='FALSE';
SET error_code='ER247';
SET info_msg='MS247';
SET event='SEASON';
ELSE/*card not expired*/
IF(stn_type='ENTRY')THEN/*CHECK EVENT BY STATION TYPE*/
SET event='SEASON';
IF(ISNULL(sea_lpn))THEN SET sea_lpn='xxxx'; END IF;
#select sea_reg_lpn,sea_lpn,_lpn,CHAR_LENGTH(_lpn);
SELECT `trans_id`,`trans_date`,`in_out` FROM sea_card_transactions WHERE trans_id=(SELECT MAX(trans_id) FROM sea_card_transactions WHERE card_no=_cardno AND site_no=mysite) INTO tea_exists,op_date,location;
IF(CHAR_LENGTH(_lpn)>=7 && _lpn!= sea_lpn && sea_reg_lpn=1)THEN
SET bool_code='FALSE';
SET error_code='ER218';
SET info_msg='MS218';
INSERT INTO numberplate_mismatches(`token_number`,`token_type`,`entry_plates`,`exit_plates`,`ptrans_id`,action_description) VALUES
(_cardno,'S-ACARD',ent_lpn,_lpn,tea_exists,'Seasonal Card mismatched and Blocked at Entry');
ELSE/*if that condition is not satisfied.tuendelee*/
#select tea_exists;
/*Lest check if there is a mismatch without blocking*/
SET event='SEASON';
IF(CHAR_LENGTH(_lpn)>=7 && _lpn!= sea_lpn)THEN
INSERT INTO numberplate_mismatches(`token_number`,`token_type`,`entry_plates`,`exit_plates`,`ptrans_id`,action_description) VALUES
(_cardno,'S-ACARD',ent_lpn,_lpn,tea_exists,'Seasonal Card mismatched but Allowed at Entry');
END IF;
/*end mismatch*/
IF(ISNULL(tea_exists) OR (location=0) OR (location=1 && DATE(NOW())>op_date))THEN/*allow entry*/
IF(tea_exists>1 && location=1)THEN UPDATE sea_card_transactions SET in_out=0,exitdate=NOW() WHERE trans_id=tea_exists AND card_no=_cardno AND site_no=mysite; END IF;
INSERT INTO sea_card_transactions(`card_no`,`trans_date`,`instation`,`entrygate`,`in_out`,`site_no`,entrydate,ass_lpn)VALUES
(_cardno,CURRENT_DATE,_station,stn_name,'1',mysite,NOW(),_lpn);
SET bool_code='TRUE';
SET error_code='ER000';
SET info_msg='MS250';
ELSE
SET bool_code='FALSE';
SET error_code='ER249';
SET info_msg='MS249';
END IF;
END IF;/*end chacking plates where plate chack setting is enforced*/
ELSEIF(stn_type='EXIT')THEN
SET event='SEASON';
IF(ISNULL(sea_lpn))THEN SET sea_lpn='xxxxxxx'; END IF;
#select sea_reg_lpn,sea_lpn,_lpn,CHAR_LENGTH(_lpn);
SELECT `trans_id`,`trans_date`,`in_out`,IFNULL(ass_lpn,'XXXXXX') FROM sea_card_transactions WHERE trans_id=(SELECT MAX(trans_id) FROM sea_card_transactions WHERE card_no=_cardno AND site_no=mysite) INTO tea_exists,op_date,location,ent_lpn;
#select sea_lpn;
IF(CHAR_LENGTH(_lpn)>=7 && (_lpn!= sea_lpn OR _lpn != ent_lpn) && (sea_reg_lpn=1 OR sea_ent_lpn=1))THEN/*is lnn check enforce*/
SET bool_code='FALSE';
SET error_code='ER218';
SET info_msg='MS218';
INSERT INTO numberplate_mismatches(`token_number`,`token_type`,`entry_plates`,`exit_plates`,`ptrans_id`,action_description) VALUES
(_cardno,'S-ACARD',sea_lpn,_lpn,tea_exists,'Seasonal Card mismatched and Blocked at Exit');
ELSE
IF(CHAR_LENGTH(_lpn)>=7 && _lpn!= sea_lpn)THEN
INSERT INTO numberplate_mismatches(`token_number`,`token_type`,`entry_plates`,`exit_plates`,`ptrans_id`,action_description) VALUES
(_cardno,'S-ACARD',ent_lpn,_lpn,tea_exists,'Seasonal Card mismatched but allowed at Exit');
END IF;
IF(location=1)THEN
UPDATE sea_card_transactions SET in_out=0,exitdate=NOW(),exitgate=stn_name,outstation=_station,ass_lpn=_lpn WHERE trans_id=tea_exists AND card_no=_cardno AND site_no=mysite;
SET bool_code='TRUE';
SET error_code='ER000';
SET info_msg='MS220';
ELSE
SET bool_code='FALSE';
SET error_code='ER221';
SET info_msg='MS221';
END IF;
END IF;
ELSE
SET bool_code='FALSE';
SET error_code='ER248';
SET info_msg='MS248';
END IF;
END IF;/*end expiry check*/
END IF;/*end check of seasonal blocked check*/
ELSE/*normal card check */
IF(stn_type='ENTRY')THEN
SET event='ENTRY';
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='sarit_apb_average' AND site_applicable=mysite LIMIT 1 INTO sarit_apb;
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='confirm_acard_record' AND site_applicable=mysite LIMIT 1 INTO confirm_insert;
SELECT SQL_CACHE setting_value,setting_validity FROM global_settings WHERE setting_name='confirm_acard_balance' AND site_applicable=mysite LIMIT 1 INTO min_entry_bal,check_entry_bal;
#SELECT transid,in_out,entry_timestamp FROM parkingtrans WHERE transid=(SELECT MAX(transid) FROM parkingtrans WHERE card_no=_cardno AND transactiontype=(2,7)) INTO sea_exists,location,time_in;
#evans. 7:12 10/22/2015
SELECT transid,in_out,entry_timestamp FROM parkingtrans WHERE transid=(SELECT MAX(transid) FROM parkingtrans WHERE card_no=_cardno AND transactiontype IN(2,7)) INTO sea_exists,location,time_in;
IF check_entry_bal=1 && min_entry_bal> _baloncard THEN
SET bool_code='FALSE';
SET error_code='ER243';
SET info_msg='MS243';
ELSEIF ISNULL(sea_exists) OR (sea_exists>=1 && location=0) OR (sea_exists>=1 && location=1 && sarit_apb=1 && DATE(time_in)< CURRENT_DATE) THEN/*card is good to enter*/
SET ent_dex="FULL ACARD ENTRY";
SET useful_transtype=2;
SELECT NOW() INTO time_in;
IF (sea_exists>=1 && location=1 && sarit_apb=1 && DATE(time_in)< CURRENT_DATE) THEN
SELECT IFNULL(crypt_key,'4545') FROM cryptonium WHERE site_no=mysite AND encrypt_start < NOW() AND (ISNULL(encrypt_end) OR encrypt_end > NOW()) INTO pass_key;
SELECT IFNULL(pass_key,'4545') INTO pass_key;
SELECT AES_ENCRYPT(0,pass_key) INTO char_amount;
SET useful_transtype=7;
UPDATE parkingtrans SET `transactiontype`=8,`in_out`=0,`bal_bf_exit`=_baloncard,`bal_af_exit`=_baloncard,
`trans_duration`=TIMESTAMPDIFF(MINUTE,time_in,CONCAT(time_in,':','23:59:59')),`amount_payable`=char_amount,`amount_paid`=char_amount,
`payment_status`=1,`pay_type`=1,`pay_activity`=0,`trans_year`=YEAR(NOW()),`trans_month`=MONTH(NOW()),`trans_date`=DATE(NOW()),`shift`='SHIFT1',
`paid_on`=NOW(),`pay_station`=_station,`site_no`=mysite,`exit_date`=DATE(NOW()),`exit_timestamp`=NOW() WHERE transid=sea_exists;
END IF;
SET ent_dex=ent_dex;
INSERT INTO `parkingtrans` (`entry_gate`, `entry_timestamp`, `datein`, `timein`, `hour_in`, `card_no`,`transactiontype`, `in_out`, `car_reg`, `face_capture`,lpn_capture, `device_no`, `veh_class`,`token_site_zone`,`site_no`,`bal_on_entry`,entry_description) VALUES
(stn_name,time_in,DATE(time_in),TIME(time_in),HOUR(time_in),_cardno,useful_transtype,1,_lpn,_fimagepath,_limagepath,ent_device,IFNULL(_vehcat,1),myzone,mysite,_baloncard,ent_dex);
SET ent_dex=ent_dex;
IF confirm_insert=1 THEN
SELECT transid FROM parkingtrans WHERE card_no=_cardno AND transactiontype=2 AND token_site_zone=myzone AND entry_timestamp=time_in LIMIT 1 INTO newest_record_id;
#select newest_record_id;
IF ISNULL(newest_record_id) THEN
SELECT CONCAT(ent_dex,' RETRY') INTO ent_dex;
INSERT INTO `parkingtrans` (`entry_gate`, `entry_timestamp`, `datein`, `timein`, `hour_in`, `card_no`,`transactiontype`, `in_out`, `car_reg`, `face_capture`,lpn_capture, `device_no`, `veh_class`,`token_site_zone`,`site_no`,`bal_on_entry`,entry_description) VALUES
(stn_name,time_in,DATE(time_in),TIME(time_in),HOUR(time_in),_cardno,useful_transtype,1,_lpn,_fimagepath,_limagepath,ent_device,IFNULL(_vehcat,1),myzone,mysite,_baloncard,ent_dex);
END IF;
END IF;
SET lastinsert=LAST_INSERT_ID();
SET bool_code='TRUE';
SET error_code='ER000';
SET info_msg='MS250';
ELSE/*card has APB*/
SET bool_code='FALSE';
SET error_code='ER249';
SET info_msg='MS249';
END IF;
ELSEIF(stn_type='EXIT')THEN
SET event='EXIT';
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='normal_LPNI' AND site_applicable=mysite INTO sea_ent_lpn;
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='sarit_apb_average' AND site_applicable=mysite LIMIT 1 INTO sarit_apb;
SELECT SQL_CACHE setting_validity FROM global_settings WHERE setting_name='pay_by_entry_zone' AND site_applicable=mysite LIMIT 1 INTO use_entry_zone;
SELECT NOW() INTO time_now;
#select sea_ent_lpn,sarit_apb,use_entry_zone;
SELECT get_current_shift(_station,time_now) INTO shift_string;
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(shift_string,'#',2),'#',-1) INTO myshift;
/*SELECT IFNULL(crypt_key,'4545') FROM cryptonium WHERE site_no=mysite AND encrypt_start < NOW() AND (ISNULL(encrypt_end) OR encrypt_end > NOW()) INTO pass_key;*/
SELECT transid,in_out,entry_timestamp,car_reg,`payment_status`,`pay_activity`,entry_description,trans_description,token_site_zone,transactiontype FROM parkingtrans WHERE transid=(SELECT MAX(transid) FROM parkingtrans
WHERE card_no=_cardno AND transactiontype IN(2,7)) INTO sea_exists,location,time_in,ent_lpn,pay_state,lipa_activity,acq_entry_dex,acq_trans_dex,entry_zone,card_trans_type;
IF(ISNULL(sea_exists) OR location=0)THEN
SET return_value=0;
SET bool_code='FALSE';
SET error_code='ER221';
SET info_msg='MS221';
ELSE
IF sea_ent_lpn=1 && ent_lpn>5 && ent_lpn != 'AIG400K' && CHAR_LENGTH(_lpn)>=7 && ent_lpn != _lpn THEN/*validate detected license plate at exit*/
SET return_value=0;
SET bool_code='FALSE';
SET error_code='ER218';
SET info_msg='MS218';
INSERT INTO numberplate_mismatches(`token_number`,`token_type`,`entry_plates`,`exit_plates`,`ptrans_id`,action_descritpion) VALUES
(_cardno,'N-ACARD',ent_lpn,_lpn,sea_exists,'Normal Card mismatched and Blocked at Exit');
ELSE
/*Lets log mismatches even if there is not blockage*/
IF ent_lpn>5 && ent_lpn != 'AIG400K' && CHAR_LENGTH(_lpn)>=7 && ent_lpn != _lpn THEN
INSERT INTO numberplate_mismatches(`token_number`,`token_type`,`entry_plates`,`exit_plates`,`ptrans_id`,action_descritpion) VALUES
(_cardno,'N-ACARD',ent_lpn,_lpn,sea_exists,'Normal Card mismatched but Allowed Out at Exit');
END IF;
/*Lets calculate a charge if sarit_apb is enacted*/
IF sarit_apb=1 AND card_trans_type=7 THEN
SELECT AVG(sarit.afrage) FROM (SELECT trans_amount AS afrage FROM acardtransactions WHERE trans_type=2 AND card_no=_cardno ORDER BY trans_id DESC LIMIT 2,5) AS sarit INTO sarit_avg_amt;
SELECT FLOOR(sarit_avg_amt) INTO sarit_avg_amt;
END IF;
/*enuf*/
/*Hallo*/
IF use_entry_zone=1 THEN
SET myzone=entry_zone;
END IF;
/*lets charge*/
SELECT FLOOR(TIMESTAMPDIFF(MINUTE,time_in,time_now)) INTO raw_duration;
IF raw_duration > 1440 THEN
SELECT FLOOR(TIMESTAMPDIFF(DAY,time_in,time_now)) INTO days_spent;
/*We check for the day rates aggressively*/
SELECT fullday_rate_sniffer(time_in,myzone,_vehcat,days_spent,mysite) INTO fd_fee;
SELECT DATE_ADD(time_in, INTERVAL days_spent DAY) INTO time_in;/*get our new time in*/
SET fd_fee=fd_fee*days_spent;
IF ISNULL(fd_fee)THEN SET fd_fee=0; END IF;#safety
END IF;
/*Lets now calculate the amount time spent on a single day*/
SELECT DAYOFWEEK(time_in) INTO dow1;
SELECT DAYOFWEEK(time_now) INTO dow2;
IF(dow1 != dow2) THEN
#SELECT myzone,dow1,_vehcat,time_in,CONCAT(DATE(time_in),' ','23:59:59');
SELECT rate_sniffer(myzone,dow1,_vehcat,time_in,CONCAT(DATE(time_in),' ','23:59:59'),'A') INTO fee1;
#SELECT myzone,dow2,_vehcat,CONCAT(DATE(time_now),' ','00:00:00'),time_now;
SELECT rate_sniffer(myzone,dow2,_vehcat,CONCAT(DATE(time_now),' ','00:00:00'),time_now,'B') INTO fee2;
ELSE
#SELECT myzone,dow1,_vehcat,time_in,time_now;
SELECT rate_sniffer(myzone,dow1,_vehcat,time_in,time_now,'A') INTO fee1;
END IF;
SET total_fee=IFNULL(fd_fee,0)+IFNULL(fee1,0)+IFNULL(fee2,0);
IF location=1 && pay_state>=1 THEN
SELECT `get_partial_total`(_cardno,'',mysite) INTO amount_charged;
SET total_fee=total_fee-IFNULL(amount_charged,0);
END IF;
SET total_fee=total_fee+IFNULL(sarit_avg_amt,0);
IF total_fee > _baloncard THEN
SET return_value=total_fee;
SET bool_code='FALSE';
SET error_code='ER243';
SET info_msg='MS243';
ELSE
SELECT trans_id FROM acardtransactions WHERE parkingtrans_transid=sea_exists AND card_no=_cardno AND DATE(time_in)=DATE(time_in) LIMIT 0,1 INTO cardrec;
IF ISNULL(cardrec) THEN
INSERT INTO `acardtransactions` (`parkingtrans_transid`, `card_no`, `trans_time`, `timein`, `timeout`, `amount_before`, `expected_amount`,`trans_station`, `merchant_id`, `site`, `trans_type`, `trans_desc`,logged) VALUES
(sea_exists,_cardno,time_now,time_in,time_now,_baloncard,total_fee,_station,merch_agent,mysite,2,'EXIT CHARGE',3);
END IF;
SET return_value=total_fee;
SET bool_code='TRUE';
SET error_code='ER000';
SET info_msg='MS000';
END IF;
END IF ;
END IF;
ELSE
SET bool_code='FALSE';
SET error_code='ER248';
SET info_msg='MS248';
END IF;/*Normal Exit Event Check*/
END IF;/*end of seasonal or normal check*/
END IF;/*end of blacklist check*/
END IF;/*end of master or blocked check*/
END IF;/*end of parameter check*/
/*lets check pending details*/
SELECT floating_value,floating_status,fid FROM floating_acard WHERE card_no=_cardno AND floating_status=1 INTO pending_value,pending,pending_id;
IF pending_id >=1 THEN
SET pending_value=IFNULL(return_value,0)-IFNULL(pending_value,0);
ELSE
SET pending_value=return_value;
END IF;
SELECT disp_msg(info_msg) INTO message_string;
SELECT CONCAT(_cardno,' # ', NOW(),' # ',stn_type,' last-record:',IFNULL(lastinsert,0)) INTO story;
SELECT get_severity(error_code) INTO error_sev;
SELECT bool_code,error_code,info_msg,message_string,IFNULL(return_value,0) AS return_value,stn_type,IFNULL(pending_value,0) AS pending_value,pending,IFNULL(pending_id,'') AS pending_id,event,story;
END$$
DELIMITER ;

1172 - Result consisted of more than one row in mysql

How can I solve this problem (Result consisted of more than one row in mysql)
DROP PROCEDURE IF EXISTS `doMarksApplication`;
CREATE PROCEDURE `doMarksApplication`(
in kuser varchar(20),
out idpro int(11))
SP:BEGIN
declare no_more_rows int default FALSE;
declare total_marks decimal(10,2) default 0;
declare idfor int(11) default 0;
declare sskod int(5) default getCurSession();
declare bdata int(5) default 0;
declare nopmh varchar(20);
# Data PB [Permohonan Baru] DM [Proses Pemarkahan]
declare cur1 cursor for
select ind_nopmh from pinduk
left join pprses on pro_nopmh = ind_nopmh
where ind_sskod = sskod and
concat(pro_stats,pro_statp) in ('PB','DM') and
not exists (select mar_idnum from pmrkah where mar_nopmh = ind_nopmh)
order by ind_nopmh;
declare continue handler for not found set no_more_rows = TRUE;
begin
select count(ind_nopmh) into bdata
from pinduk
left join pprses on pro_nopmh = ind_nopmh
where ind_sskod = sskod and
concat(pro_stats,pro_statp) in ('PB','DM') and
not exists (select mar_idnum from pmrkah where mar_nopmh = ind_nopmh);
end;
begin
select count(for_idnum) into idfor from xkod_markah_00_formula
where for_stats = 'A' and
curdate() between for_tkhdr and for_tkhhg;
end;
if idfor = 1 and sskod <> 0 then
begin
select for_idnum into idfor from xkod_markah_00_formula
where for_stats = 'A' and
curdate() between for_tkhdr and for_tkhhg;
end;
begin
insert into pprmar
(pma_tkmla,pma_msmla,pma_puser,pma_sskod,pma_idfor,pma_bdata)
values
(curdate(),curtime(),kuser,sskod,idfor,bdata);
end;
begin
select last_insert_id() into idpro;
end;
open cur1;
LOOP1:loop
fetch cur1 into nopmh;
if no_more_rows then
close cur1;
leave LOOP1;
end if;
begin
call getMarksAnakPerak(nopmh,#total_perak);
call getMarksAkademik(nopmh,#total_akdmk);
call getMarksSosioekonomi(nopmh,#total_sosio);
end;
set total_marks = #total_perak + #total_akdmk + #total_sosio;
begin
insert into pmrkah
(mar_idpro,mar_nopmh,mar_idfor,mar_perak,mar_akdmk,mar_sosio,mar_total)
values
(idpro,nopmh,idfor,#total_perak,#total_akdmk,#total_sosio,total_marks);
end;
begin
update pprses
set pro_stats = 'D',
pro_statp = 'M',
pro_tkmsk = curdate(),
pro_msmsk = curtime(),
pro_kuser = kuser
where pro_nopmh = nopmh;
end;
end loop;
begin
update pprmar
set pma_tktmt = curdate(),
pma_mstmt = curtime()
where pma_idnum = idpro;
end;
end if;
END;
i have been programming in mysql for 15 years and this is easily the most confusing stored procedure i have ever seen.
None the less, one possible place for your issue is here
select for_idnum into idfor from xkod_markah_00_formula
where for_stats = 'A' and
curdate() between for_tkhdr and for_tkhhg;
I know it does not seem to be the reason but without knowing the content of the other three stored procedures you are calling this is the only candidate. You should add a limit 1 to it, and to every select into statement that reads from a table (i.e. not a sum() or a count() etc...) as that would always have the potential to cause the error you are seeing.
select for_idnum into idfor from xkod_markah_00_formula
where for_stats = 'A' and
curdate() between for_tkhdr and for_tkhhg limit 1;
In addition, you should comment out the three stored procedure calls and see if the error goes away. My guess is that the issue is one of those stored procedures due to a select into similar to above has more than one row in the result set but does not use limit 1 and does not filter properly.

Case not working for my stored procedure

I have created this procedure to insert upc_id and relevent values in the table product_universal_description.
CREATE PROCEDURE veealpha
(
IN s_po_id INT(11),
IN s_supplier_id INT(11),
IN s_location_id VARCHAR(32),
IN s_warehouse_id INT(11),
IN s_user_id INT(11),
OUT message VARCHAR(64),
OUT error_code INT(4)
)
BEGIN
DECLARE temp_upc VARCHAR(32);
DECLARE i INT;
DECLARE finished INTEGER DEFAULT 0;
DECLARE loop_count int(4);
DECLARE upc varchar(32);
DECLARE p_product_id int(11);
DECLARE p_model varchar(64);
DECLARE counter_cursor CURSOR FOR
SELECT product_id,model,quantity FROM product
WHERE model in('CFB0040','CFB0042','CFB0043','CFB0044')
AND quantity > 0;
DECLARE CONTINUE HANDLER FOR 1062
SET message = 'Duplicate Keys Found';
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET finished = 1;
OPEN counter_cursor;
add_data : LOOP
FETCH counter_cursor INTO p_product_id, p_model, loop_count;
SET i = 1;
WHILE loop_count > 0 DO
CASE i
WHEN i < 10 THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-000',i);
WHEN (i >= 10 AND i < 100) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-00',i);
WHEN (i >= 100 AND i < 1000) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-0',i);
ELSE
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-',i);
END CASE;
INSERT INTO product_universal_description
(
`upc_id`,
`po_id`,
`supplier_id`,
`location_id`,
`warehouse_id`,
`product_id`,
`model_no`,
`added_by`,
`updated_by`,
`date_added`,
`date_modified`
) VALUES (
temp_upc,
s_po_id,
s_supplier_id,
s_location_id,
s_warehouse_id,
p_product_id,
p_model,
s_user_id,
s_user_id,
NOW(),
NOW()
);
SET i=i+1;
SET loop_count = loop_count - 1;
END WHILE;
IF finished = 1 THEN
LEAVE add_data;
END IF;
END LOOP add_data;
CLOSE counter_cursor;
END
CALL veealpha(123,45,'UP',1,56,#msg,#err);
ON Execution I getting the result like this.
How ever I have given the conditions there for UPC_ID that it should be well mannered as per case. But leaving for i = 1 FOR all it takes the ELSE condition at CASE. Can anybody tell me .. what's wrong happened and how could i get the desired result.
Try:
...
-- CASE i
CASE
WHEN i < 10 THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-000',i);
WHEN (i >= 10 AND i < 100) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-00',i);
WHEN (i >= 100 AND i < 1000) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-0',i);
ELSE
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-',i);
END CASE;
...