I've the following code in a stored procedure:
DECLARE done INT DEFAULT FALSE;
declare v_degree int(11);
declare v_start_age smallint(6);
declare v_end_age smallint(6);
declare v_gender varchar(20);
declare v_calctable varchar(200);
SELECT calculationtable into v_calctable FROM wac.degrees where tablename = concat("cdb_" + arg_tablename);
declare cur CURSOR for select degree, start_age, end_age, belt, gender from v_calctable;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
Like this I'll get a syntax error in the line "SELECT calculationtable into v_calctable FROM wac.degrees where tablename = concat("cdb_" + arg_tablename);"
If I put it after the "Declare cursor" there's no syntax error, but I need the result to be used on de Cursor select statement.
How can I accomplish this?
Thanks.
CREATE DEFINER=`root`#`localhost` PROCEDURE `my_procedure`()
BEGIN
DECLARE done INT DEFAULT FALSE;
declare v_degree int(11);
declare v_start_age smallint(6);
declare v_end_age smallint(6);
declare v_gender varchar(20);
declare v_calctable varchar(200);
SELECT calculationtable into v_calctable FROM wac.degrees where tablename = concat("cdb_" + arg_tablename);
begin -- write here begin keyword
declare cur CURSOR for select degree, start_age, end_age, belt, gender from v_calctable;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
end; -- end here inner block
END
when you use inner block by another begin and end keyword
then it have no syntask error .
but this procedure give you correct result or not i am not clear
Related
Here is the reference link that I used to create procedures: https://dba.stackexchange.com/questions/7147/find-highest-level-of-a-hierarchical-field-with-vs-without-ctes/7161#7161?newreg=88de047579d242c98b8cfe0e17f0330f
Procedures are working well with the example. But not working in my own database. Seems I do something wrong while creating procedures.
Here is the procedure for my db:
DELIMITER $$
DROP FUNCTION IF EXISTS `demo`.`GetParentIDByID` $$
CREATE FUNCTION `demo`.`GetParentIDByID` (GivenID INT) RETURNS INT
DETERMINISTIC
BEGIN
DECLARE rv INT;
SELECT IFNULL(user_by,-1) INTO rv FROM
(SELECT user_by FROM users WHERE id = GivenID) A;
RETURN rv;
END $$
DELIMITER ;
Sql query for the following procedure is working fine. It is basically getting parent_id of the node:
SELECT id,GetParentIDByID(id) FROM users;
Issue occurs when I am try to get Ancestors. Here is the Procedure that I am using:
DELIMITER $$
DROP FUNCTION IF EXISTS `demo`.`GetAncestry` $$
CREATE FUNCTION `demo`.`GetAncestry` (GivenID INT) RETURNS VARCHAR(1024)
DETERMINISTIC
BEGIN
DECLARE rv VARCHAR(1024);
DECLARE cm CHAR(1);
DECLARE ch INT;
SET rv = '';
SET cm = '';
SET ch = GivenID;
WHILE ch > 0 DO
SELECT IFNULL(user_by,-1) INTO ch FROM
(SELECT user_by FROM users WHERE id = ch) A;
IF ch > 0 THEN
SET rv = CONCAT(rv,cm,ch);
SET cm = ',';
END IF;
END WHILE;
RETURN rv;
END $$
DELIMITER ;
SQL query:
SELECT id,GetAncestry(id) FROM users;
Phpmyadmin getting stuck, if I am using this query. It never returns me anything nor an error or success
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 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.
here is my trigger:
create trigger wyplacamy before insert on `skladki_wyplaty`
for each row
BEGIN
SELECT p.wysokosc_skladki, p.ilosc_miesiecy INTO #wysokosc_skladki, #ilosc_miesiecy
FROM skladki_aktualne p
WHERE p.pesel = NEW.pesel AND p.id_ubezpieczenia = NEW.id_ubezpieczenia;
SET NEW.wyoskosc_wyplaty = #wysokosc_skladki / #ilosc_miesiecy *75;
END
$$
This works, but the iutpput of "wyoskosc_wyplaty" is NULL, even wysokosc_skladki = 8000, and ilosc_miesiecy = 8.
You need to declare the variables before using them.
delimiter $$
create trigger wyplacamy before insert on `skladki_wyplaty`
for each row
BEGIN
DECLARE var_wysokosc_skladki INT;
DECLARE var_ilosc_miesiecy INT;
SELECT p.wysokosc_skladki, p.ilosc_miesiecy INTO var_wysokosc_skladki, var_ilosc_miesiecy
FROM skladki_aktualne p
WHERE p.pesel = NEW.pesel
AND p.id_ubezpieczenia = NEW.id_ubezpieczenia;
SET NEW.wyoskosc_wyplaty = var_wysokosc_skladki / var_ilosc_miesiecy * 75;
END
$$
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?