inserting multiple(many ) rows into table in one time - mysql

how to inset into mysql table,example INSERT INTO users(user_id,time,)VALUES(1-500,1524275145) in my case need insert into TABLE users 500 rows form 1-500(it's users id) with same values time for all users.

I tried this one, it is working:
First you execute this snippet to create a procedure in your database so that we can call it later (the second snippet) and execute the query that will insert the 1-500 values into the users user_id column. (You can see the two variables that have values of 500 and 1, and you can see the line: VALUES (user_id_val, 1524275145) where the query will be executed.)
First snippet: (try to execute it separately from the next one)
DROP PROCEDURE IF EXISTS insert_loop;
DELIMITER #
CREATE PROCEDURE insert_loop()
BEGIN
DECLARE user_id_max INT UNSIGNED DEFAULT 500;
DECLARE user_id_val INT UNSIGNED DEFAULT 1;
START transaction;
WHILE user_id_val < user_id_max+1 DO
INSERT INTO users (user_id, time)
VALUES (user_id_val, 1524275145);
SET user_id_val = user_id_val + 1;
END WHILE;
COMMIT;
END #
Second snippet:
DELIMITER ;
CALL insert_loop();
Execute this after the first one (separately).

An example query for your case would be like this:
INSERT INTO users (user_id,time) VALUES
(1, 1524275145),
(2, 1524275145),
(3, 1524275145),
(4, 1524275145);
And so on, until 500. The best approach would be to create the query in a for loop.

Related

Create sql procedure but it's not appeared in the table

there is no error but also doesn't show success
at first, it shows on only table registrations and not the registration_details, and now doesn't appear in both table.
set foreign_key_checks = 0;
drop procedure if exists createRegist;
delimiter //
create procedure createRegist()
begin
declare total_credit float;
declare registration_id INT;
declare credit float;
-- create first registration for student 1
set total_credit = 0;
insert into `student_regist`.`registrations` (`registration_id`, `student_id`,`total_credit`)
values (1, 1, total_credit);
SELECT LAST_INSERT_ID() INTO registration_id;
-- create registration detail 1
SELECT
`student_regist`.`courses`.`credit`
INTO credit FROM
`student_regist`.`courses`
WHERE
`student_regist`.`courses`.`course_id` = 1
LIMIT 1;
set total_credit = total_credit + credit;
insert into `student_regist`.`registration_details` (`registration_details_id`, `registration_id`, `course_id`, `semester`)
values (1, 1, 1, 1);
SELECT 'Success';
end//
delimiter ;
You have not provided nearly enough detail for us to provide any concrete answers. Adding the DDL for your tables to your question is the minimum required for a real answer.
That said, here are some suggestions.
We know nothing of the values you need to store in credit (and total_credit) but it seems likely that it should be DECIMAL, and not FLOAT. Searching decimal vs float on here returns Float vs Decimal in ActiveRecord as the first result.
If you are using MySQL Workbench the errors/warnings should be displayed in the Output Area (View -> Panels -> Show Output Area). Or you could run SHOW WARNINGS; after calling your SP.
CALL createRegist();
SHOW WARNINGS;
Your first insert into registrations uses a hardcoded value of 1 for registration_id, which is presumably the primary key (PK) for the table. The second time you execute the SP and it tries to insert 1 into your PK, it will fail with a duplicate key error -
Error Code: 1062. Duplicate entry '1' for key 'registrations.PRIMARY'
You then follow up with the call for LAST_INSERT_ID() which will not work as you are expecting. From the MySQL docs -LAST_INSERT_ID()
The value of LAST_INSERT_ID() is not changed if you set the AUTO_INCREMENT column of a row to a non-“magic” value (that is, a value that is not NULL and not 0).
Changing the value passed in the insert statement to NULL or 0 (or removing completely) will resolve this -
/* Passing in value of NULL */
set total_credit = 0;
insert into `student_regist`.`registrations` (`registration_id`, `student_id`,`total_credit`)
values (NULL, 1, total_credit);
/* or removing completely */
set total_credit = 0;
insert into `student_regist`.`registrations` (`student_id`,`total_credit`)
values (1, total_credit);

mysql procedure with if condition

I'm in my first databases class and I'm trying to write a conditional block for a mysql procedure.
This is the procedure:
delimiter //
CREATE PROCEDURE add_ascent(IN cid INT, IN pid INT)
BEGIN
DECLARE count_ascents INT;
SET count_ascents = 0;
SELECT COUNT(`cid`) INTO count_ascents FROM ascents WHERE `cid`=cid AND `pid`=pid;
IF count_ascents < 1 THEN
INSERT INTO ascents (`cid`, `pid`) VALUES (cid, pid);
UPDATE climbers SET climbers.ascents = climbers.ascents + 1 WHERE climbers.id=cid;
UPDATE problems SET problems.ascents = problems.ascents + 1 WHERE problems.id=pid;
END IF;
END;
//
delimiter ;
The goal of the procedure is to only perform the insert and updates if the (cid, pid) pair is not in the the ascents database. After testing, the program doesn't seem to go into the if block at all.
FYI, you might want to consider using an UPSERT, instead of "select/if/insert". For example, mySQL offers INSERT ON DUPLICATE KEY UPDATE.
Here, I suggest:
giving your parameters a DIFFERENT name than the column name, for example iCid and iPid, then
Typing SELECT COUNT(cid) INTO count_ascents FROM ascents WHERE cid=iCid AND pid=iPid and checking the result.

MySQL stored procedure performance issue when using cursor and temporary table

I tried to replace heavy Java method which runs multiple requests to the DB with stored SQL procedure.
It's doing its work but I expected much higher performance improvement.
The logic of the procedure(as well as Java method):
Get list of IDs from table1(purpose)
Iterate the list and get average value of a field from table2(record) for each id
Return list
of pairs id/average_value
Are there any efficiency issues in the procedure?
DROP PROCEDURE IF EXISTS test1.getGeneralAverage;
CREATE DEFINER=root#localhost PROCEDURE getGeneralAverage()
BEGIN
DECLARE p_id BIGINT(20);
DECLARE exit_loop BOOLEAN;
DECLARE cur CURSOR FOR
SELECT purpose_id FROM purpose
WHERE purpose.type = 'GENERAL'
AND (SELECT COUNT(*) > 0 FROM record
WHERE record.purpose_id=purpose.purpose_id) is true;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
CREATE TEMPORARY TABLE IF NOT EXISTS general_average
(id BIGINT(20), average DOUBLE) ENGINE=memory;
TRUNCATE TABLE general_average;
OPEN cur;
average_loop: LOOP
FETCH cur INTO p_id;
INSERT INTO test1.general_average (id, average)
VALUES (p_id, (SELECT AVG(amount) FROM record
WHERE record.purpose_id=p_id));
IF exit_loop THEN
CLOSE cur;
LEAVE average_loop;
END IF;
END LOOP average_loop;
INSERT INTO test1.general_average (id, average)
VALUES (0,
(select avg(amount) from record where purpose_type='CUSTOM'));
SELECT * FROM general_average;
END
Several patterns to change...
Try to avoid CURSORs; usually the entire operation can be done with a single SQL statement. That will be much faster.
INSERT ... VALUES (0, ( SELECT ... ) ) --> INSERT ... SELECT 0, ...
Don't use a TEMP table when you can simply deliver the results. In your case, you may need a UNION ALL to deliver the two chunks at once.

Creating variables in MySQL Triggers

Please have a look at the below SQL Query.
DELIMITER $$
CREATE TRIGGER `Portfolio_AINS` AFTER INSERT ON `Portfolio` FOR EACH ROW
INSERT INTO Initial_Fees (idPortfolio, Current_Time_Stamp, Initial_Gross_Fee, Initial_Monetary_Fee)
VALUES (
New.idPortfolio,
current_timestamp,
(New.Invest_Amount*(New.Initial_Gross_Fee/100)),
(New.Invest_Amount*(New.Initial_Gross_Fee/100))*(New.Initial_Company_Fee/100)
)
In here, the Initial_Monetary_Fee = Initial_Gross_Fee * (New.Initial_Company_Fee/100)
But I have written it (New.Invest_Amount*(New.Initial_Gross_Fee/100))*(New.Initial_Company_Fee/100)
Instead of that, I would like to create variables and assign the values to them, so I can avoid such long calculations. For an example, something like below.
InitialGrossFee = (New.Invest_Amount*(New.Initial_Gross_Fee/100))
IntialMonetaryFee = InitialGrossFee * (New.Initial_Company_Fee/100)
So, how can I create such variables and store values in side MySQL triggers? I prefer to have some explanation as well.
If you need multiple statements within in a trigger you must use BEGIN .... END.
Then you can assign values to uservars as usual:
CREATE TRIGGER `Portfolio_AINS` AFTER INSERT ON `Portfolio`
FOR EACH ROW
BEGIN
SET #grossfee := New.Invest_Amount*(New.Initial_Gross_Fee/100);
INSERT INTO Initial_Fees (idPortfolio, Current_Time_Stamp, Initial_Gross_Fee, Initial_Monetary_Fee)
VALUES (
New.idPortfolio,
current_timestamp,
#grossfee,
#grossfee *(New.Initial_Company_Fee/100)
);
END$$

Error 1111: mysql on trigger from insert

I am trying to understand why this trigger keeps giving me an error about invalid use of grouped function when i try to run a basin insert statement to test this out.
I have tried working with this to figure out what i am doing wrong but the error just remains the same. Error 1111
DROP TRIGGER a_num;
DELIMITER //
CREATE TRIGGER a_num BEFORE INSERT ON test_a
FOR EACH ROW BEGIN
DECLARE last INT DEFAULT 0;
INSERT INTO test_b SET full_name = CONCAT_WS(' ', NEW.f_name, NEW.l_name);
SET last = COUNT(id);
UPDATE test_b SET number = CONCAT_WS('-', last, LEFT(NEW.f_name, 2), LEFT(NEW.f_name, 2)) WHERE id = last;
END;
//
Please don't mind the use or poor construction I quite a newb.
Thanks.
I think it should be -
DROP TRIGGER a_num;
DELIMITER //
CREATE TRIGGER a_num BEFORE INSERT ON test_a
FOR EACH ROW BEGIN
DECLARE last INT DEFAULT 0;
INSERT INTO test_b SET full_name = CONCAT_WS(' ', NEW.f_name, NEW.l_name);
SET last = LAST_INSERT_ID();
UPDATE test_b SET number = CONCAT_WS('-', last, LEFT(NEW.f_name, 2), LEFT(NEW.f_name, 2)) WHERE id = last;
END;
//
Can you provide the CREATE statement for test_a and the INSERT statement you're using?
In MySQL Workbench if you right click on test_a go to Copy to Clipboard..Create Statement, will send the table definition.
Is there a reason you're inserting and then updating the same record? Could you combine this into one insert?