I have following stored procedure :
mysql> call generateSerial('param1',1,#serial);
Query OK, 0 rows affected (0.00 sec)
mysql> select #serial;
+--------------+
| #serial |
+--------------+
| 100000000033 |
+--------------+
I want to use above #serial for each row from select query, something like:
select #serial ,...
from table_test;
and with each row, #serial are difference by difference procedure execute
I know that procedure can not be executed in select stm
But I also can not using function because I need using a transaction to get #serial
have any chance for me about this case ;
Here is one way creating a second procedure that loops over the table rows and calls the generate serial procedure for each row.
CREATE PROCEDURE run()
BEGIN
DECLARE serial VARCHAR(32);
DECLARE col_int INT;
DECLARE col_varchar VARCHAR(10);
DECLARE done INT DEFAULT FALSE;
DECLARE query CURSOR FOR SELECT column_int, column_varchar FROM t;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN query;
q: LOOP
FETCH query into col_int, col_varchar;
IF done THEN
LEAVE q;
END IF;
CALL GenerateSerial(col_varchar,col_int,serial);
select serial;
END LOOP;
CLOSE query;
END;
SQL Fiddle
Related
I have a question about the stored procedure:
Create a stored procedure named format_currency that accepts a character and a double number. It will return a VARCHAR(32) with the symbol in the front, followed by the number to 2 decimal places.
For example, format_currency('$', 123.4) should return $123.40
Here is my code:
CREATE OR REPLACE PROCEDURE format_currency(IN c VARCHAR2, IN n DOUBLE(9,2))
AS
BEGIN
SELECT CONCAT(c,',' n);
END;
It's not working, I have no idea how to write codes inside BEGIN and END.
Many Thanks for your help.
Henry
Instead of procedure I suggest to use function:
Code:
DELIMITER $$
DROP FUNCTION IF EXISTS test_f$$
CREATE FUNCTION test_f(a varchar(22),b double(9,2)) returns varchar(64)
BEGIN
SET #RET = (select concat(a,b));
return #RET;
END$$
DELIMITER ;
Test Run:
mysql> select test_f('$',123);
+-----------------+
| test_f('$',123) |
+-----------------+
| $123.00 |
+-----------------+
1 row in set (0.10 sec)
mysql>
DELIMITER\\
CREATE PROCEDURE format_currency (a CHAR, b DOUBLE(9,2))
BEGIN
declare ret VARCHAR(32);
set #ret = (SELECT CONCAT(a,b));
select #ret;
END
DELIMITER\\
call format_currency('$',123);
I had a similar question and nothing the other people answered worked for me in MySQL. Here is a working solution with 2 parameters as "SIGN" and "MONEY" and creating a variable called "NEWRESULT" that you delcare, set as 0, and then set as the concat of "SIGN" and "MONEY".
DELIMITER //
CREATE PROCEDURE format_currency`enter code here`
(IN SIGN char(1),IN MONEY double(9,2))
BEGIN
declare NEWRESULT char(8);
set NEWRESULT=0;
SET NEWRESULT=(SELECT CONCAT(SIGN,MONEY));
SELECT NEWRESULT;
END//
DELIMITER ;
I've created a procedure where I have 2 in parameters and 1 out parameter. However, I don't know why my output doesn't want to come out. I don't want to use a select statement. I would like to use the out parameter. Thanks.
create procedure quiz_totals(in q1 double unsigned, in q2 double unsigned, out p_total int)
begin
declare v_ceil_q1 int;
declare v_ceil_q2 int;
declare v_max int;
declare v_min int;
set v_ceil_q1 := ceiling(q1);
set v_ceil_q2 := ceiling(q2);
create table temp_tbl(t_scores int);
insert into temp_tbl(t_scores) values(v_ceil_q1), (v_ceil_q2));
select max(t_scores) into v_max from temp_tbl;
select min(t_scores) into v_min from temp_tbl;
set p_total := (v_ceil_q1) + (v_ceil_q2) + v_max - 2*v_min;
drop table temp_tbl;
end;
#
delimiter ;
call quiz_totals(23, 32.4, #total);
This is my output:
Query OK, 0 rows affected (0.02 sec)
No p_total ! Why?
You need a select, even if you don't want to...
SELECT #total;
If you wanna see what's inside !
I need a helper table with only one int(11) column, that contains a row for each consecutive number from 1 to a given max. Can this be done with pure SQL?
Example:
INSERT INTO `helper`('itnum') VALUES (1),(2),(3),...(999999),(1000000);
I need a statement like this, but without explicitly listing all the entries to be made.
How about something like this:
DELIMITER |
DROP PROCEDURE IF EXISTS insert_helper_records |
CREATE PROCEDURE insert_helper_records(a_max INTEGER)
BEGIN
DECLARE v_iteration INTEGER;
SET v_iteration := 1;
insert_loop: LOOP
INSERT INTO helper(itnum) VALUES (v_iteration);
SET v_iteration := v_iteration + 1;
IF v_iteration = a_max THEN
LEAVE insert_loop;
END IF;
END LOOP;
END |
DELIMITER ;
Then call it however you want like:
SELECT insert_helper_records(999999) FROM DUAL;
i think to do this, you have to execute your insert inside a loop in your SGBD procedure, or outside (php script, ...).
Problem:
Hi I've got two stored procedures, that I try to run from another one.
- If I call them one after the other from phpmysqladmin, everything works fine.
- If I call the stored procedure, that calls the other two, I don't get an error. So far so good. But the problem is, that the operations from the second stored procedure aren't executed.
Already tried to run it in just one sp...
I also tried to run both stored procedures (sp1,sp2) in one stored procedure, with the same effect.
Could that be the problem?
In the first sp I use a statement like this:
Select #var:= ....
Here is the code:
In the first stored procedure I generate a dynamic query and execute it.
Procedure 1
CREATE PROCEDURE `sp_prepare_valid_choices`(IN p_request_id Bigint)
BEGIN
DECLARE num_rows INT DEFAULT 0;
DECLARE no_more_rows BINARY;
DECLARE no_more_subrows BINARY;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE var_choice_group BIGINT DEFAULT 0;
-- Declare Cursor for the loop through the constraint_groups
DECLARE cur_constraint_group CURSOR FOR
SELECT distinct choice_constraint_group FROM casainte_choice_constraint
WHERE choice_id_rule_parameter IN (SELECT choice_id FROM casainte_request_detail
where request_id = p_request_id);
-- DECLARE 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows := TRUE;
-- DELETE OLD VALUES
DELETE FROM tmp_casainte_valid_choices
WHERE request_id = p_request_id;
DELETE FROM tmp_casainte_valid_choices_for_request
WHERE request_id = p_request_id;
-- OPEN CURSOR AN PROCESS CONSTRAINT_GROUPS
OPEN cur_constraint_group;
SELECT FOUND_ROWS() INTO num_rows;
choice_group_loop: LOOP
FETCH cur_constraint_group
INTO var_choice_group;
IF no_more_rows THEN
CLOSE cur_constraint_group;
LEAVE choice_group_loop;
END IF;
-- PAYLOAD
-- INSERT THE VALID CHOCIES INTO tmp_casainte_valid_choices
SELECT #var_sql_query := CONCAT('INSERT INTO tmp_casainte_valid_choices ','SELECT ',p_request_id,' as request_id, `casainte_choice_constraint`.`choice_constraint_id`,`casainte_choice_constraint`.`choice_constraint_group`
,AVG(IF (`casainte_request_detail`.`choice_varchar_value`', `casainte_choice_constraint`.`choice_constraint_operator`, '\'',`casainte_choice_constraint`.`choice_constraint_value`, '\'',',1,0 )) AS VALID
FROM `casainte_choice_constraint`
LEFT JOIN `casainte_request_detail` ON `casainte_request_detail`.`choice_id` = `casainte_choice_constraint`.`choice_id_rule_parameter`
WHERE `casainte_choice_constraint`.choice_constraint_group =' , var_choice_group,
' GROUP BY `casainte_choice_constraint`.choice_constraint_group')
FROM `casainte_choice_constraint` WHERE `casainte_choice_constraint`.choice_constraint_group = var_choice_group;
PREPARE SQL_STATEMENT FROM #var_sql_query;
EXECUTE SQL_STATEMENT;
-- INCREMENT THE COUNTER
SET loop_cntr = loop_cntr + 1;
END LOOP choice_group_loop;
END$$
Procedure 2
In the second stored procedure I insert the values into a table.
delimiter $$
CREATE PROCEDURE `sp_insert_valid_choices`(IN p_request_id Bigint)
BEGIN
INSERT INTO tmp_casainte_valid_choices_for_request
(request_id, choice_id)
SELECT DISTINCT p_request_id, choice_id FROM casainte_choice ac
-- RULE 1 ALL CHOICES WITHOUT CONSTRAINTS
WHERE ac.choice_id NOT IN (SELECT choice_id_rule_target FROM casainte_choice_constraint)
-- RULE 2 ALL CHOICES WITH CONSTRAINTS, THAT ARE NOT YET ANSWERED
OR ac.choice_id NOT IN (SELECT choice_id_rule_target FROM casainte_choice_constraint
WHERE choice_id_rule_parameter IN (SELECT choice_id FROM casainte_request_detail WHERE request_id = p_request_id))
-- RULE 3 ALL CHOICES WITH CONSTRAINTS, THAT ARE TRUE
OR ac.choice_id IN (SELECT choice_id_rule_target FROM casainte_choice_constraint
WHERE choice_constraint_group IN (SELECT choice_constraint_group FROM tmp_casainte_valid_choices WHERE request_id = p_request_id AND VALID = 1));
END$$
Procedure 3
The third stored procedure calls the 1st sp, then the 2nd sp.
delimiter $$
CREATE PROCEDURE `sp_generate_valid_choices`(IN p_request_id Bigint)
BEGIN
Call `sp_prepare_valid_choices`(p_request_id);
Call `sp_insert_valid_choices`(p_request_id);
END$$
You don't have "delimiter $$" at the top of Procedure 1. Could this be causing the problem?
I am learning stored procedures, cursors in mysql and I stumble on it:
delimiter //
CREATE PROCEDURE some_func()
BEGIN
DECLARE link_rewrite VARCHAR(255);
DECLARE link_rewrite_cursor CURSOR FOR SELECT link_rewrite FROM prod;
OPEN link_rewrite_cursor;
SET #count = 0;
WHILE #count < 10 DO
FETCH link_rewrite_cursor INTO link_rewrite;
SELECT link_rewrite;
set #count = #count + 1;
END WHILE;
CLOSE link_rewrite_cursor;
END//
delimiter ;
My question is: Why SELECT link_rewrite always returns NULL (in prod table there is 9000 rows). SELECT link_rewrite FROM prod returns a lot of rows(9000 rows).
You should avoid using the same name for multiple different things. Specifically, give the variable a different name than the column you are selecting. For example, if you rename the variable v_link_rewrite then it will probably work:
delimiter //
DROP PROCEDURE IF EXISTS some_func //
CREATE PROCEDURE some_func()
BEGIN
DECLARE v_link_rewrite VARCHAR(255);
DECLARE link_rewrite_cursor CURSOR FOR SELECT link_rewrite FROM prod;
OPEN link_rewrite_cursor;
SET #count = 0;
WHILE #count < 10 DO
FETCH link_rewrite_cursor INTO v_link_rewrite;
SELECT v_link_rewrite;
set #count = #count + 1;
END WHILE;
CLOSE link_rewrite_cursor;
END//
delimiter ;
If you just want to select the top 10 rows, do this:
select link_rewrite from prod limit 10
It's much quicker and you don't have to go with a cursor.