Reputation: 1523
I am looking to automate a procedure I am handling manually now. So, I am new to stored procedures and the code below is not working.
It stops when it outputs the first set of variables of the SELECT statement. It does not do the UPDATE and does not continue with the WHILE loop. No errors are reported.
DELIMITER //
CREATE PROCEDURE ins_die_1()
BEGIN
DECLARE v_yr INT;
DECLARE v_col CHAR(10);
DECLARE v_base INT;
DECLARE v_factor INT;
DECLARE v_cf INT;
DECLARE v_fuel CHAR(10);
SET v_yr :=1;
SET v_col := '';
SET v_base := 2860;
SET v_factor := 1;
SET v_cf := 5;
SET v_fuel := 'diesel';
WHILE v_yr <= 5 DO
SET v_col := CONCAT('ins_yr',v_yr);
SELECT v_col, v_base, v_factor, v_fuel, v_cf;
UPDATE ct_insurance
SET v_col = (v_base + 1254 + (v_factor * .0032 * price ))
WHERE fuel = v_fuel
AND CF=v_cf
AND price * v_factor < 162000
AND version_id = 1746;
SET v_yr := v_yr+1;
IF v_yr = 2 THEN SET v_factor := .8;
ELSE SET v_factor := v_factor - 0.1;
END IF;
END WHILE;
END//
DELIMITER ;
I know that there is the IN construct, whereby I should enter the variables manually when calling the procedures, but that seems like an awkward solution and certainly not very efficient.
In case you wonder I have many variables, it's because this is a test procedure. Once it works, hopefully, I will expand it.
Also, I am looking for a mySql solution only, ie, no php involved.
Upvotes: 0
Views: 3022
Reputation: 780818
Column names in the UPDATE
statement are taken literally, variables don't substitute there. You can do it using dynamic SQL:
SET @sql = CONCAT('UPDATE ct_insurance
SET ', v_col, ' = (v_base + 1254 + (v_factor * .0032 * price ))
WHERE fuel = v_fuel
AND CF=v_cf
AND price * v_factor < 162000
AND version_id = 1746');
PREPARE stmt FROM @sql;
EXECUTE stmt;
However, you can't access procedure local variables from prepared statements (see here) so you need to use user-defined @
variables.
DELIMITER //
CREATE PROCEDURE ins_die_1()
BEGIN
DECLARE v_yr INT;
DECLARE v_col CHAR(10);
SET v_yr :=1;
SET v_col := '';
SET @v_base := 2860;
SET @v_factor := 1;
SET @v_cf := 5;
SET @v_fuel := 'diesel';
SELECT v_col, @v_base, @v_factor, @v_fuel, @v_cf;
WHILE v_yr <= 5 DO
SET v_col := CONCAT('ins_yr',v_yr);
SET @sql = CONCAT('UPDATE ct_insurance
SET ', v_col, ' = (@v_base + 1254 + (@v_factor * .0032 * price ))
WHERE fuel = @v_fuel
AND CF = @v_cf
AND price * @v_factor < 162000
AND version_id = 1746');
PREPARE stmt FROM @sql;
EXECUTE stmt;
SET v_yr := v_yr+1;
IF v_yr = 2 THEN SET v_factor := .8;
ELSE SET v_factor := v_factor - 0.1;
END IF;
END WHILE;
END//
Upvotes: 2