insert large volume of data in mysql - mysql

I want to insert atleast 500,000 fresh records in one shot. For which I have used while loop inside procedure. My query is working fine but it is taking alot of time to execute. So, I am looking for a solution using which I can make the process of insertion of large volume of data faster. I have gone through many links but I didn't find them resourceful.
Note:
I want to insert fresh data, not the data from existing table.
Syntactically the code provided below is correct and working. So please do not provide any suggestions regarding syntax.
Below is my procedure:
BEGIN
DECLARE x INT;
DECLARE start_s INT;
DECLARE end_s INT;
SET x = 0;
PREPARE stmt FROM
'insert into primary_packing(job_id, barcode, start_sn, end_sn, bundle_number, client_code, deno, number_sheets, number_pins, status)
values (?,?,?,?,?,?,?,?,?,?)';
SET #job_id = job_id, #barcode = barcode, #bundle_number = bundle_number, #client_code = client_code, #deno = deno, #number_sheets = number_sheets, #number_pins = number_pins, #status = 1;
set #start_sn = start_sn;
set #end_sn = end_sn;
WHILE x <= multiply DO
set #start_s = (start_sn+(diff*x));
set #end_s = ((end_sn-1)+(diff*x)+diff);
EXECUTE stmt USING #job_id, #barcode, #start_s, #end_s, #bundle_number, #client_code, #deno, #number_sheets, #number_pins ,#status;
SET x = x + 1;
END WHILE;
DEALLOCATE PREPARE stmt;
END

Use MYSQL command LOAD DATA INFILE to load your .csv files records to specific table.
For more information and eg. please reffer the following link
http://dev.mysql.com/doc/refman/5.1/en/load-data.html

Related

MySql Stored procedure WHERE "variabilised" according to a parameter

I'm totally new with stored procedure and I'm trying to understand its basic concepts. This is my first one and of course there is something wrong.
Basically the query is going to be the same (the original is more complex and there are other operations) but the WHERE clause changes according to the selType param. So what I'm trying to do is a sort of "variabilisation" of the WHERE clause according to the param value.
I don't know whether this is the correct approach and, if yes, what's wrong with it.
DELIMITER //
CREATE PROCEDURE `testProcedure` (IN addressId INT, IN selType BOOLEAN)
BEGIN
DECLARE whereUserCriteria VARCHAR(127);
IF selType = 1 THEN
SET whereUserCriteria = CONCAT('address_id = ', addressId);
ELSE
SET whereUserCriteria = 'address_id = 1';
END IF;
SELECT whatever
FROM wherever AS ad
WHERE whereUserCriteria ;
END //
It's nice to see that when it's not variabilised, it works perfectly but, as soon as i use a variable to make it dynamic, it stops working.
Of course this is a mere example aimed to understand what's the best approach in cases like this.
You can prepare query concatenating the queries and condition together and execute that using Prepared Execute statement as follows(as mentioned in the comment above):
DELIMITER //
CREATE PROCEDURE `testProcedure` (IN addressId INT, IN selType BOOLEAN)
BEGIN
DECLARE whereUserCriteria VARCHAR(127);
IF selType = 1 THEN
SET whereUserCriteria = CONCAT('address_id = ', addressId);
ELSE
SET whereUserCriteria = 'address_id = 1';
END IF;
SET #myQuery = '';
SET #myQuery = CONCAT("SELECT whatever FROM wherever AS ad
WHERE ",whereUserCriteria,") ;
PREPARE stmQuery FROM #myQuery;
EXECUTE stmQuery;
DEALLOCATE PREPARE stmQuery;
END //
DELIMITER ;
You probably want do dynamic query.
But you can rewrite your sample using CASE like this (but not sure if that is what you want):
SELECT whatever
FROM wherever AS ad
WHERE address_id = CASE WHEN selType = 1
THEN addressId
ELSE 1
END;

MySQL Stored Procedure Search another table

I am totally new to Stored Procedures, but know that this could be more efficient than trying to write PHP+MySQL code each time I need to do something like this.
I have two tables. CapitalAssets, Systems
I want find all CapitalAssets.ServerName that are not null
I have to link the two tables together, the Systems table has IP addresses, hostname.
I want to (row-by-row) grab CapitalAssets.ServerName and search Systems.hostname, IF it is found I want to link/print
CapitalAssests: Systems.id, Systems.hostname, Systems.IP, CapitalAssets.id, CapitalAssets.ServerName
Here is my start to my stored procedure, It is wrong. I do not now how to pass the Systems.hostname to do the search (where the ? is)
begin
declare GSATcur cursor for
'select id,NEName,ManagementAddress FROM GSAT WHERE NEName like ?';
declare CapitalCurr CURSOR FOR
'SELECT id,SystemName FROM CapitalAssets WHERE SystemName != ""';
DECLARE start INT DEFAULT 0;
DECLARE sysname_not_found BOOL DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET sysname_not_found = TRUE;
OPEN GSATcur;
OPEN CapitalCur;
loop1:
WHILE start < 5 do
FETCH SystemName INTO NEName;
IF sysname_not_found THEN
LEAVE loop1;
END IF;
END WHILE;
CLOSE CapitalCur;
CLOSE GSATcur;
END;
The two tables are in the same dB.
" grab CapitalAssets.ServerName and search Systems.hostname, IF it is found I want to link/print "
If this is the ultimate goal. Try this
SELECT * FROM Systems
WHERE hostname IN ( SELECT DISTINCT(ServerName)
FROM CapitalAssets WHERE ServerName IS NOT NULL );
UPDATE CapitalAssets
INNER JOIN Systems
ON Systems.hostname = CapitalAssests.ServerName
SET CapitalAssets.ipAddress = Systems.ipAddress;
UPDATE CapitalAssets
SET ipAddress = ( SELECT ipAddress
FROM Systems
WHERE Systems.hostname = CapitalAssests.ServerName );

Why does MySQL find an error in the CONCAT statement?

I'm trying to write a stored procedure in MySQL, where I need to loop on a cursor, and execute an SQL statement that uses a piece of data from the cursor that gets fetched into a variable, then executed as SQL. The cursor orders_cur is sorted on this_addr; in a given block of this_addr records, the first record is skipped, and the rest need to be flagged by setting the duplicateorder="1".
For some reason, I cannot get the line with the CONCAT function to work without giving me an error:
OPEN orders_cur;
order_loop: LOOP
-- Now loop on orders_cur until this_addr = match_addr
find_addr_loop: REPEAT
FETCH orders_cur INTO this_addr,this_orderid;
UNTIL this_addr = match_addr
END REPEAT;
-- Skip the first order that matched by performing another fetch
FETCH orders_cur INTO this_addr,this_orderid;
-- Now start next loop which does the real work; set duplicateorder on the remaining records in cursor,
-- using the orders_cur.order_id to locate the actual record in the Reservations table.
set_dupe_loop: WHILE this_addr = match_addr
SET #sql = CONCAT('UPDATE Reservations SET duplicateorder = \'1\' WHERE order_id=',this_orderid);
PREPARE runme FROM #sql;
EXECUTE runme;
FETCH orders_cur INTO this_addr,this_orderid;
END WHILE set_dupe_loop:;
DEALLOCATE PREPARE runme;
END LOOP order_loop;
I have tried every variation possible on escaping the literals that I need around the '1' to no avail, and am going cross-eyed...if anyone sees where my error lies, I would very much appreciate it...
--rixter
You don't need a cursor for this operation. You can do:
UPDATE Reservations r JOIN
(SELECT this_addr, MIN(order_id) as minoi
FROM Reservations r2
WHERE this_addr = match_addr
GROUP BY this_addr
) dups
ON r.this_addr = dups.this_addr and r.order_id > dups.minoi
SET r.duplicateorder = 1;
In general, you should avoid cursors, especially those that require dynamic SQL. When you can express the logic as a set operation, it is usually best to do so.
Nothing wrong with the CONCAT, the loop is not initiated/enclosed properly.
This set_dupe_loop: WHILE this_addr = match_addr
should be this set_dupe_loop: WHILE this_addr = match_addr DO

MySQL generates many new result-set

I've got MySQL procedure which I execute in MySQL Workbench. The problem is that it generates many new result-set, and GUI client show it (...many times) -
I found solution, which I can use instead just select clause to avoid generating result-sets. It looks like:
SELECT EXISTS(
SELECT ...
)
INTO #resultNm
Unfortunately it won't work with LIMIT ?,1 where ? is my variable 'i'. I also cant use just 'i' instead % because I am working on MySQL 5.1 (and limit clauses can't be done in other way). So my question - are other possibilities to hide result-sets?
CREATE PROCEDURE LOOPDOSSIERS(starter integer, finish integer)
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE row_oid binary(16);
DECLARE row_str VARCHAR(256);
DECLARE row_old VARCHAR(256);
SET i=starter;
WHILE i<finish DO
-- SET row_str = ();
SET #row_str = 'select CAST(concat(d.prefixe_numero,d.numero) as CHAR) from courrier_concerne_dossier as x
join dossier as d on
d.oid = x.dossier_oid limit ?,1';
PREPARE stmt1 FROM #row_str;
EXECUTE stmt1 USING #i;
SET #row_oid = 'select x.courrier_oid
from courrier_concerne_dossier as x
join dossier as d on
d.oid = x.dossier_oid LIMIT ?,1';
PREPARE stmt2 FROM #row_oid;
EXECUTE stmt2 USING #i;
select dossiers_str from courrier_envoye where oid = row_oid into row_old;
update courrier_envoye set dossiers_str = CAST(CONCAT(row_str, " ", row_old) AS CHAR) where oid = row_oid;
SET i = i + 1;
END WHILE;
End;
;;
LIMIT without an ORDER BY clause doesn't have a well defined behavior. For your parameters to work in a sensible way, you'll need to order by something. The starter and finish variables aren't very meaningful at the moment, but it's currently not clear what they're intended to be.
I think you can probably accomplish this whole procedure in a single query using the syntax in this answer (also probably much faster). That probably won't work with LIMIT, but I'd highly recommend using a range of some kind in the where clause rather than a limit anyway.

MySQL 1329 Error No Data - Zero rows fetched

I have searched SO, for similar and I found one other posting similar to this and I followed what I thought was the follow up but I'm still seeing a problem.
I have also been sifting through the MySQL manuals, and what I have here looks like it is correct.
DELIMITER $$
CREATE DEFINER=`perimUser`#`localhost` PROCEDURE `assignLOBId`()
BEGIN
declare id, done INT default 0;
declare name VarChar(45);
declare lobCursor Cursor for Select idLineOfBusiness as id, name from LineOfBusiness;
declare continue handler for not found set done = 1;
OPEN lobCursor;
my_loop: LOOP
FETCH lobCursor INTO id, name;
IF done = 1 THEN
CLOSE lobCursor;
LEAVE my_loop;
END IF;
insert into test values (id, name);
UPDATE medium set idLOB = id where LOB = name;
UPDATE low set idLOB = id where LOB = name;
End LOOP my_loop;
END
I have run the Query that I"m using for the cursor and it does return 13 rows. Tables medium and low are full of data about 600 rows in each. the LOB match values in the LOB column of each. The values that were used to create the ones in lineofbusiness were generated from medium and low.
The goal here is to use this pattern a number of times as I work to normalized the data in medium and low. Otherwise I'd take the short cut and create a bunch of manual update statements.
I'm not too sure why your cursor isn't working as expected (you don't say whether your test table is populated with the results that you expect?), but it appears to me your procedure is simply implementing a multiple-table UPDATE (so can probably be entirely replaced with the following):
UPDATE LineOfBusiness
LEFT JOIN medium ON LineOfBusiness.name = medium.LOB
LEFT JOIN low ON LineOfBusiness.name = low.LOB
SET medium.idLOB = LineOfBusiness.idLineOfBusiness
, low.idLOB = LineOfBusiness.idLineOfBusiness