I have created the following stored proc in MySQL:
BEGIN
DECLARE temp_mold VARCHAR(30);
DECLARE temp_time DATETIME;
DECLARE temp_shot_ct INT;
DECLARE temp_shot_count INT;
DECLARE temp_shot_mold VARCHAR(30);
DECLARE temp_shot_cavity_count INT;
DECLARE temp_job_count INT;
DECLARE temp_row_count INT;
DECLARE done INT DEFAULT 0;
DECLARE temp_shot_counter INT DEFAULT 1;
DECLARE setup_time INT;
DECLARE cursor1 CURSOR FOR
SELECT
(schedule_run_time*3600)/(schedule_qty/schedule_cavity_count) as shot_ct,
ROUND((schedule_qty/schedule_cavity_count)) as shot_count,
schedule_mold as shot_mold, schedule_cavity_count as shot_cavity_count
FROM `schedule`
WHERE `schedule`.schedule_cell = start_cell AND `schedule`.schedule_date = DATE(start_time) AND deleted = 0
ORDER BY schedule_order ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SELECT COUNT(schedule_id) INTO temp_job_count FROM `schedule` WHERE schedule_cell = start_cell AND schedule_date = DATE(start_time) AND deleted = 0;
SELECT cell_setup_standard INTO setup_time FROM cells WHERE cell_name = start_cell;
DROP TEMPORARY TABLE IF EXISTS rst;
CREATE TEMPORARY TABLE rst (
shot_id INT NOT NULL AUTO_INCREMENT,
shot_datetime datetime,
shot_qty INT,
PRIMARY KEY (shot_id)
);
SET temp_time = start_time;
SET temp_mold = "";
SET temp_row_count = 0;
INSERT INTO rst (shot_datetime) VALUES (temp_time);
#Loop through cursor1 recordset
OPEN cursor1;
start_loop: LOOP
FETCH cursor1 INTO temp_shot_ct, temp_shot_count, temp_shot_mold, temp_shot_cavity_count;
IF done THEN
LEAVE start_loop;
END IF;
IF temp_mold <> temp_shot_mold THEN
SET temp_time = TIMESTAMPADD(MINUTE,setup_time,temp_time); #Add standard setup time whenever the mold changes
INSERT INTO rst (shot_datetime) VALUES (temp_time);
SET temp_mold = temp_shot_mold;
END IF;
SET temp_shot_counter = 1;
REPEAT
SET temp_time = TIMESTAMPADD(SECOND,temp_shot_ct,temp_time);
INSERT INTO rst (shot_datetime,shot_qty) VALUES (temp_time,temp_shot_cavity_count);
SET temp_shot_counter = temp_shot_counter + 1;
UNTIL temp_shot_counter > temp_shot_count
END REPEAT;
END LOOP;
CLOSE cursor1;
#Return records. Will be used in ORM to loop through records on the PHP side
SELECT SUM(shot_qty) AS qty, HOUR(shot_datetime) AS shot_hour FROM rst GROUP BY HOUR(shot_datetime);
DROP TEMPORARY TABLE IF EXISTS rst;
END
I'm not the greatest at using stored procedures. This one is running very slow - it takes about 6 seconds to run. The queries individually run in milliseconds, so I was expecting this to take 100 milliseconds at most. I can't figure out what I'm doing wrong that's causing this to run so slowly. Does anyone have any ideas on how to make this run quicker? I can create a PHP script to do the same thing, but I'm trying to get better at using stored procs and functions in MySQL - and this is far less code. I welcome any and all advice.
Related
I try to set a trigger before I insert a value into table ec3_checking, the trigger's function is set 'account_id' to 'CH-n' if the highest value for id_count is (n-1), id_count is an auto_increment parameter.
delimiter //
CREATE TRIGGER account_id_add BEFORE INSERT ON `ec3_checking`
FOR EACH ROW
BEGIN
DECLARE anum int;
DECLARE bnum int;
SET bnum = max(id_account);
SET anum = bnum + 1;
SET NEW.account_id = concat('CH-', anum);
END//
Then I try to insert some values into the table
insert into `ec3_checking` (balance, overdraft_limit)
VALUES
('300','50');
There is an error:1111, invalid use of group function, could anyone help me?
Thank you very much.
CREATE TRIGGER `account_id_add` BEFORE INSERT ON `ec3_checking`
FOR EACH ROW BEGIN
DECLARE anum int;
SET #bnum = (SELECT max(id_account) FROM ec3_checking);
SET anum = #bnum + 1;
SET NEW.account_name = concat('CH-', anum);
END
I have written a stored procedure in mysql which will create a TEMPORARY TABLE, I want to access the data of TEMPORARY TABLE using Codeigniter.But when I call "$this->db->query()" it returns empty data.
$data=array();
$call_procedure = "CALL sp_Stock()";
$query = $this->db->query($call_procedure);
$sql="SELECT * FROM StockTable";
$query1 = $this->db->query($sql);
I have changed my way to show the data. And I do changes it on stored procedure.
DELIMITER $$
CREATE PROCEDURE sp_Stock()
BEGIN
DECLARE cursor_finish INTEGER DEFAULT 0;
DECLARE m_numofpurchaseBag DECIMAL(10,2)DEFAULT 0;
DECLARE m_purchasedKg DECIMAL(10,2)DEFAULT 0;
DECLARE m_purBagDtlId INTEGER DEFAULT 0;
DECLARE stockCursor CURSOR FOR
SELECT purchase_bag_details.`actual_bags`,
(purchase_bag_details.`net`*purchase_bag_details.`actual_bags`) AS PurchasedKg,
purchase_bag_details.`id` AS PurchaseBagDtlId
FROM
purchase_invoice_detail
INNER JOIN
purchase_bag_details
ON purchase_invoice_detail.`id`= purchase_bag_details.`purchasedtlid`
INNER JOIN
`do_to_transporter`
ON purchase_invoice_detail.`id` = do_to_transporter.`purchase_inv_dtlid`
WHERE purchase_invoice_detail.`teagroup_master_id`=6
AND purchase_invoice_detail.`id`=1481
AND do_to_transporter.`in_Stock`='Y';
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET cursor_finish = 1;
DROP TEMPORARY TABLE IF EXISTS StockTable;
#temptable creation
CREATE TEMPORARY TABLE IF NOT EXISTS StockTable
(
purchaseBagDtlId INT,
purchasedBag NUMERIC(10,2),
purchasedKg NUMERIC(10,2),
blendedBag NUMERIC(10,2),
blendedKg NUMERIC(10,2),
stockBag NUMERIC(10,2),
stockKg NUMERIC(10,2)
);
#temptable creation
OPEN stockCursor ;
get_stock : LOOP
FETCH stockCursor INTO m_numofpurchaseBag,m_purchasedKg,m_purBagDtlId;
IF cursor_finish = 1 THEN
LEAVE get_stock;
END IF;
/*SELECT m_numofpurchaseBag,m_purchasedKg,m_purBagDtlId; */
/* Blending bag query*/
SET #m_numberofBlndBag:=0;
SET #m_BlndKg:=0;
/* Blend bag*/
SELECT #m_numberofBlndBag:=SUM(blending_details.`number_of_blended_bag`) AS belendedBag INTO #m_numberofBlndBag
FROM blending_details
WHERE blending_details.`purchasebag_id`= m_purBagDtlId
GROUP BY
blending_details.`purchasebag_id`;
#Blend Bag
#Blend Kgs
SELECT #m_BlndKg:=SUM(blending_details.`qty_of_bag` * blending_details.`number_of_blended_bag`) AS blendkg INTO #m_BlndKg
FROM blending_details
WHERE blending_details.`purchasebag_id`= m_purBagDtlId
GROUP BY
blending_details.`purchasebag_id`;
SET #m_StockBag:=(m_numofpurchaseBag - #m_numberofBlndBag);
SET #m_StockKg:=(m_purchasedKg - #m_BlndKg);
INSERT INTO StockTable
(
purchaseBagDtlId ,
purchasedBag ,
purchasedKg ,
blendedBag ,
blendedKg ,
stockBag ,
stockKg
)VALUES(m_purBagDtlId,m_numofpurchaseBag,m_purchasedKg,#m_numberofBlndBag,#m_BlndKg,#m_StockBag,#m_StockKg);
END LOOP get_stock;
CLOSE stockCursor;
SELECT * FROM StockTable;
#DROP TABLE StockTable;
END$$
DELIMITER ;
#CALL sp_Stock();
Anywhere I am using a temp table I am executing this before the temp table is created:
$this->db->query('DROP TABLE IF EXISTS StockTable');
I seem to remember reading someone having the same problem as you and for some reason you have to execute the above first.
So try:
$data=array();
$call_procedure = "CALL sp_Stock()";
$this->db->query('DROP TABLE IF EXISTS StockTable');
$query = $this->db->query($call_procedure);
$sql="SELECT * FROM StockTable";
$query1 = $this->db->query($sql);
I have table name "tmp1" which has fields name id and comma. comma contains 1,3,2,4,5 values with text datatype.
I want separate value in loop in my stored procedure. Like 1 then 3 then 2 etc. So, I was create below given procedure.
BEGIN
DECLARE my_delimiter CHAR(1);
DECLARE split_comma text;
DECLARE done INT;
DECLARE occurance INT;
DECLARE i INT;
DECLARE id INT;
DECLARE sel_query VARCHAR(500);
DECLARE splitter_cur CURSOR FOR SELECT id,comma from tmp1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
OPEN splitter_cur;
splitter_loop:LOOP
FETCH splitter_cur INTO id,split_comma;
SET occurance = LENGTH(split_comma) - LENGTH(REPLACE(split_comma,',',''))+1;
SET my_delimiter=',';
IF done = 1 THEN
LEAVE splitter_loop;
END IF;
IF occurance > 0 THEN
SET i = 1;
WHILE i <= occurance DO
SET sel_query = "SELECT SUBSTRING_INDEX(comma,',',i) as abc from tmp1";
SET #sel_query = sel_query;
PREPARE sel_query FROM #sel_query;
EXECUTE sel_query;
SET i = i + 1;
END WHILE;
END IF;
SET occurance = 0;
END LOOP;
CLOSE splitter_cur;
END;
But when I execute this procedure error occurs "MySQL said: #1054 - Unknown column 'i' in 'field list'"
But here i is a variable used to rotate loop.
Is there any solution? Please help me ... Thank you in advance ...
You have to embed value of variable i in the query, which you did not do.
Change:
SET sel_query = "SELECT SUBSTRING_INDEX(comma,',',i) as abc from tmp1";
SET #sel_query = sel_query;
To:
SET #sel_query = CONCAT( "SELECT SUBSTRING_INDEX(comma,',',", i, ") as abc from tmp1 )";
I want to do a Migration data from one table to another.
I wrote a simple PHP script for my purposes but I wanted to do this by MySql script using user defined variables:
the PHP script looks like this:
//MIGRATION
$sql = "SELECT position FROM ts_user_config WHERE position != '' AND position NOT REGEXP '^-?[0-9]+$' GROUP BY TRIM(position) ORDER BY position";
$positions = db_loadColumn( $sql );
foreach ($positions as $key => $pos) {
$sql = "SELECT id FROM user_positions where UPPER(position) = UPPER('$pos')";
$posId = db_loadResult($sql);
if ($posId == null) {
$sql = "INSERT INTO user_positions (position, `desc`) VALUES ('$pos', '$pos')";
db_exec($sql);
$posId = db_insert_id();
}
$sql = "UPDATE ts_user_config SET position='$posId' WHERE TRIM(position)='$pos'";
db_exec($sql);
}
//---------
Could somebody be so kind and rewrite this PHP instructions to MySQL script? I tried to do this but my mySQL knowledge is very low and I couldn't done that.
Please help me if its not too much effort.
Thank you in advance.
I Have DONE IT !!!!!! :)
this is my mySQL script, I dont know if its perfect but its do what I need. Please tell me if I can make something better here. Thanks again :)
drop procedure if exists PositionMigration;
delimiter '//'
CREATE PROCEDURE PositionMigration()
BEGIN
BLOCK1: BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE pos VARCHAR(100);
DECLARE posId1 INT;
DECLARE posId2 INT;
DECLARE sql1 CURSOR FOR SELECT position FROM ts_user_config WHERE position != '' AND position NOT REGEXP '^-?[0-9]+$' GROUP BY TRIM(position) ORDER BY position;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN sql1;
read_loop: LOOP
FETCH sql1 INTO pos;
IF done THEN
LEAVE read_loop;
END IF;
BLOCK2: BEGIN
DECLARE posNotFound INT DEFAULT FALSE;
DECLARE sql2 CURSOR FOR SELECT id FROM user_positions where UPPER(position) = UPPER(pos);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET posNotFound = TRUE;
OPEN sql2;
FETCH sql2 INTO posId1;
IF posNotFound THEN
INSERT INTO user_positions (position, \`desc\`) VALUES (pos, pos);
BLOCK3: BEGIN
DECLARE sql3 CURSOR FOR SELECT LAST_INSERT_ID();
OPEN sql3;
FETCH sql3 INTO posId2;
UPDATE ts_user_config SET position=posId2 WHERE TRIM(position)=pos;
CLOSE sql3;
END BLOCK3;
ELSE
UPDATE ts_user_config SET position=posId1 WHERE TRIM(position)=pos;
END IF;
CLOSE sql2;
END BLOCK2;
END LOOP;
CLOSE sql1;
END BLOCK1;
END;
//
delimiter ';'
call PositionMigration();
MySQL Procedure
DELIMITER $$
DROP procedure `verifica_nf` $$
CREATE PROCEDURE `verifica_nf` (IN _id_servidor_val BIGINT, IN _nr_periodo_val INT)
BEGIN
DECLARE nota INT;
DECLARE falta INT;
-- Declare variables used just for cursor and loop control
DECLARE no_more_rows BOOLEAN;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;
-- CURSOR--
DECLARE NF_CUR CURSOR FOR
-- //////////////////////////////////////////////////////////////// --
-- // VERIFICA SE E PERIODO ATIVO // --
-- //////////////////////////////////////////////////////////////// --
SELECT
DISTINCT
a.nr_notafinal,
cr.nr_faltas
FROM
pmc_servidor s
INNER JOIN pat_avaliacao a ON s.id_servidor = a.id_servidor
INNER JOIN pat_avaliacaoetapa ae ON a.id_avaliacao = ae.id_avaliacao
INNER JOIN pat_cronograma cr ON s.id_servidor = cr.id_servidor
AND cr.nr_periodo = a.nr_periodo
WHERE
s.id_servidor = _id_servidor_val AND
a.nr_periodo = _nr_periodo_val;
-- Declare 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_rows = TRUE;
OPEN NF_CUR;
the_loop: LOOP
FETCH NF_CUR INTO nota, falta;
IF no_more_rows THEN
LEAVE the_loop;
END IF;
SELECT nota, falta;
END LOOP the_loop;
END;
$$
PHP Script
<?php
require_once("inc/con.php");
$db = ADONewConnection('mysqli');
$db->debug=1;
$db->PConnect("localhost","root","xxxxx","database");
$id = '1197614';
$period = 1;
$stmt = "CALL verifica_nf('$id','$periodo')";
$rs = $db->Execute($stmt);
echo $rs;
?>
The PHP script returns nota and falta value of database variables, but returns too the name of
database variables. Like this:
(mysqli): CALL verifica_nf('1197614','1')
nota,falta 10000,1
How can I get the values in a PHP variable?