For testing, is it possible to run a loop from MySQL workbench or similar tool? I tried but got an error.
If it is possible, please supply a simple example I can run.
You can't do a for loop in an SQL editor without a stored procedure. I use TOAD for MySQL.
A quick stored procedure should do the job:
DELIMITER $$
DROP PROCEDURE IF EXISTS proc_loop_test$$
CREATE PROCEDURE proc_loop_test()
BEGIN
DECLARE int_val INT DEFAULT 0;
test_loop : LOOP
IF (int_val = 10) THEN
LEAVE test_loop;
END IF;
SET int_val = int_val +1;
SELECT int_val;
END LOOP;
END$$
DELIMITER ;
There's a trick with limited use-cases that is "loop-like".
I wanted to create a large (1~2 million) row table of random integers for a test:
INSERT INTO test_table (num) VALUES(ROUND(RAND() * 1E6));
-- calling this will insert once for every row in test_table
INSERT INTO test_table (num)
SELECT ROUND(RAND() * 1E6)
FROM test_table;
So I quickly just kept doubling the number of rows until I had what I needed.
Supposed that you already have an arbitrary table myOldTable which is sufficiently long you could use the following trick:
set #counter = 0;
select (#counter := #counter+1), #counter*#counter from myOldTable limit 1000;
If it is that you only want to block the current thread then use select sleep(seconds); otherwise you can use a stored procedure (if there's something you want to loop over) or a UDF (user defined function).
Related
I am creating this basic procedure using MySQL Workbench to accept a single input parameter.
The table "unique_days" has a single PRIMARY KEY column called "dayid" which currently has a single ROW with a value of 1.
DROP PROCEDURE IF EXISTS dayid_iteration;
DELIMITER $$
CREATE PROCEDURE dayid_iteration(maxdate_final INT)
BEGIN
DECLARE maxdate_current INT;
SET #maxdate_current = (SELECT (MAX(dayid) + 1) FROM unique_days);
DELETE FROM unique_days WHERE dayid > 1;
WHILE (maxdate_current > maxdate_final) DO
INSERT INTO unique_days (dayid) VALUES (maxdate_current);
SET maxdate_current = (maxdate_current+1);
END WHILE;
END$$
DELIMITER ;
The procedure is then called with an integer parameter.
CALL dayid_iteration(11);
The variables are setting properly because I can run a select statement with the variable and it shows the correct new value. The deletion of dayid > 1 also works (Tested by manually adding additional rows, and then running procedure). However, I can't seem to get the WHILE statement to insert new rows with the value provided.
Any help is much appreciated. I searched multiple other questions, and countless forums, but everything looks like it should be working.
I am expecting the code to CREATE 9 ROWS for a total of 10 ROWS.
The following is included just so you can see the starting values of the table.
SELECT * FROM unique_days;
For anyone who finds this question, the following code functions correctly. The input variable on the parameter was not setting properly. Once the parameter had "IN" placed in front of the variable name, it correctly received the parameter.
CREATE PROCEDURE dayid_iteration(IN maxdate_final INT)
DROP PROCEDURE IF EXISTS dayid_iteration;
DELIMITER $$
CREATE PROCEDURE dayid_iteration(IN maxdate_final INT)
BEGIN
DECLARE maxdate_current INT;
SET maxdate_current = (SELECT (MAX(dayid) + 1) FROM unique_days);
WHILE (maxdate_current <= maxdate_final) DO
INSERT INTO unique_days (dayid) VALUES (maxdate_current);
SET maxdate_current = (maxdate_current+1);
END WHILE;
END$$
DELIMITER ;
CALL dayid_iteration(1000);
This call procedure now properly works.
CALL dayid_iteration(1000);
I created a little program to show my students how to use loops in MySQL (Workbench).
The program updates a column in a table with test data. I want to add a range of interest rates. When I run the program, the same interested rate is entered into each row.
CREATE TABLE mtgPayment
(lengthMonths DECIMAL(4,0),
mInterest DECIMAL(8,6),
loanAmt DECIMAL(10,2));
DELIMITER $$
CREATE PROCEDURE test_data()
BEGIN
DECLARE i DECIMAL(8,6) DEFAULT 2.0;
WHILE i < 3.5 DO
UPDATE mtgpayment set mINTEREST = i;
SET i = i + .5;
END WHILE;
END$$
DELIMITER ;
CALL test_data();
SELECT * FROM mtgpayment;
I want to grab a variable (between 1-365) and use this value to create the number of empty rows in a table:
insert into tblCustomer (ID) values (), (), ();
is there an easier way to do this or is using a loop the best way?
Any help would be appreciated.
A procedure with an IN parameter is quite easy
DELIMITER $$
DROP PROCEDURE IF EXISTS test_loop$$
CREATE PROCEDURE test_loop(IN number INT)
BEGIN
DECLARE x INT(11);
SET x = 1;
WHILE x <= number DO
INSERT INTO tblCustomer(id) VALUES('');
SET x = x + 1;
END WHILE;
END$$
DELIMITER ;
How to use it
CALL test_loop(20);
I need to utilize two insert statements in a single procedure in order to update a master and detail table, so I'm trying to use the delimiter keyword for this to work. I'm using phpMyAdmin 3.5.8, client libmysql - 5.0.96, and mysql 5.1.70. I've tried all sorts of syntax, but none seem to work. This is my query:
DELIMITER //
CREATE PROCEDURE `agregarPrincipio` (IN ID_PRODUCTO INT UNSIGNED, IN DESCR VARCHAR(100))
BEGIN
START TRANSACTION;
INSERT INTO `TM_PRINCIPIO_ACTIVO` (`DESCRIPCION`) VALUES(DESCR);
INSERT INTO TD_PRINCIPIO_ACTIVO(`ID_TD_PRINCIPIO_ACTIVO`,`ID_TM_PRINCIPIO_ACTIVO`) VALUES(ID_PRODUCTO,LAST_INSERT_ID());
COMMIT;
END
//
DELIMITER ;
Any ideas on what may be happening?
the problem is in the line
INSERT INTO TD_PRINCIPIO_ACTIVO(`ID_TD_PRINCIPIO_ACTIVO`,`ID_TM_PRINCIPIO_ACTIVO`) VALUES(ID_PRODUCTO,LAST_INSERT_ID());
. You are trying to directly call a stored procedure LAST_INSERT_ID() in your second select statement. If LAST_INSERT_ID() returns a single value, try to save it in a variable. Then use that variable
DECLARE last_id int default 0;
SET last_id= SELECT LAST_INSERT_ID(); #if it is a function other wise use exec
INSERT INTO TD_PRINCIPIO_ACTIVO(`ID_TD_PRINCIPIO_ACTIVO`,`ID_TM_PRINCIPIO_ACTIVO`) VALUES(ID_PRODUCTO,last_id);
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, ...).