MySQL migrate data from one table to another - mysql

I'm attempting to move data from one table to another, as part of a restructure to the database architecture. I'm using PHPMyAdmin and MySQL to do so.
The SQL is meant to, for each emergency_contacts.id, move e_c.id and e_c.activity_id to activities_emergency_contacts, where the pair will form a composite key to link a contact with an activity.
The following SQL returns an error:
CREATE PROCEDURE dowhile()
BEGIN
SET #cid = (SELECT MIN(`id`) FROM `emergency_contacts`);
SET #aid = (SELECT `activity_id` FROM `emergency_contacts` WHERE `id` = #cid);
WHILE #cid IS NOT NULL DO
INSERT INTO activities_emergency_contacts (activity_id, contact_id)
VALUES (#aid, #cid);
SET #cid = (SELECT MIN(id) FROM emergency_contacts WHERE #cid < id);
SET #aid = (SELECT activity_id FROM emergency_contacts WHERE id = #cid);
END WHILE;
END;
CALL dowhile();
SQL query:
CREATE PROCEDURE dowhile() BEGIN SET #cid = (SELECT MIN(id) FROM
emergency_contacts)
MySQL said:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
I have searched the MySQL specific documentation to try and find any issues with my SET, WHILE, BEGIN/END, INSERT, CREATE - just about every line. I'm unsure how to proceed. Any advice would be greatly appreciated.
EDIT: I missed a closing bracket inside the WHILE on SELECT MIN (id), however I've fixed this and am still getting the exact same issue.
EDIT: The issue was that I was not using DELIMITER. Correct SQL:
DELIMITER $$
CREATE PROCEDURE dowhile()
BEGIN
SET #cid = (SELECT MIN(`id`) FROM `emergency_contacts`);
SET #aid = (SELECT `activity_id` FROM `emergency_contacts` WHERE `id` = #cid);
WHILE #cid IS NOT NULL DO
INSERT INTO activities_emergency_contacts (activity_id, contact_id) VALUES (#aid, #cid);
SET #cid = (SELECT MIN(id) FROM emergency_contacts WHERE #cid < id);
SET #aid = (SELECT activity_id FROM emergency_contacts WHERE id = #cid);
END WHILE;
END$$
DELIMITER ;
CALL dowhile();

Related

Same SQL runs fast in QUERY but very slowly in SP?

I had tried to add or remove the '#' before variables or params but nothing happened.
QUERY
start transaction;
set #recordClient = (select ClientId from by_test_db1.recordcd where SN = 'abc' );
set #logClient = (select ClientId from by_test_db1.log where SN = 'abc' );
select concat(#recordClient,#logClient);
commit;
SP
delimiter $$
create procedure TEST(newSN varchar(50))
begin
start transaction;
set #recordClient = (select ClientId from by_test_db1.recordcd where SN = newSN );
set #logClient = (select ClientId from by_test_db1.log where SN = newSN );
select concat(#recordClient,#logClient);
commit;
end $$
delimiter ;
call TEST('abc');
MySQL version 5.7
Through there are 100 million rows in the recordcd table ,the QUERY just ran fast and well, but the SP was running so slowly that it timed out and reported an error
Error Code: 2013. Lost connection to MySQL server during query
I tried many ways but none of them worked, I don't know why there is such a ridiculous situation, I don't even know how to search the answer to this situation.
Add indexes
INDEX(SN) -- on both tables
Simplify query
SELECT CONCAT(
( select ClientId from by_test_db1.recordcd where SN = 'abc' ),
( select ClientId from by_test_db1.log where SN = 'abc' ) );

MySQL procedure returning wrong value (INSERT SELECT confronting)

I'm completely new to MySQL, and have been bumping with some errors, but always I do find solutions, except for this one I can't understand how to get around it.
The following MySQL Procedure returns me a value if variable "ue" is 1 or 0 (a bunch of exists validation). The validation part (SET ue = EXISTS...) works without the rest of the code, as it should, the problem is not there. But when I do execute the command INSERT INTO SELECT, it does not work, it always return 0 as response, when it should be 1. These two lines are getting in confrontation with each other.
INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1;
SELECT ue AS response;
The procedure should add 'user id' and 'event id' into meetup_participation, and then update the row at 'users' corresponding to the user with that 'user id' to increment the 'events participated'. And it also UPDATE to increment the participation in the event with this 'event id'.
I am using the SET ue to validate things like, if user exists, if event does exists, if date of event is still valid, and if user is not already in this table. So I am passing this value as a boolean to INSERT INTO meetup_participation [...] WHERE ue = 1. After that, I do SELECT ue to inform validation returned true and procedure executed without problems.
Here is the full procedure.
CREATE DEFINER=`user`#`localhost` PROCEDURE `join_event`(IN `user_id` BIGINT(64), IN `event_id` INT) NOT DETERMINISTIC MODIFIES SQL DATA SQL SECURITY DEFINER
begin
DECLARE ue INT;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) AND EXISTS(SELECT 1 FROM meetup WHERE date > NOW() AND meet_id = event_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND participants <= max_participants) AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id);
INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1;
UPDATE users SET events_participated = events_participated + 1 WHERE fb_uid=user_id AND ue=1;
UPDATE meetup SET participants = participants + 1 WHERE meet_id=event_id AND ue=1;
SELECT ue AS response;
end
Thanks in advance.
The INSERT statement is executed separately from the SET ue =... statement. I'm not sure what you are trying to accomplish, but the code makes no sense.
If you want to add records to meetup_participation based on the EXISTS tests applied to each record in the users table, you would need to apply the tests to each record in your SELECT statement as part of the INSERT.
There are also numerous syntax/grammar issues in the code as shown.
If you could provide an explanation of what you are trying to accomplish with the procedure, that might allow someone to suggest the right way to code the procedure.
Selecting ue will not tell you if the procedure completed without error. You should research mysql transactions and mysql error handling. http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ is a good starting point.
You might end up with something like this
drop procedure if exists p;
delimiter //
CREATE DEFINER=`root`#`localhost` PROCEDURE `p`(
IN `inue` int,
IN `user_id` BIGINT(64),
IN `event_id` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
COMMENT ''
begin
DECLARE ue INT;
declare exit handler for sqlexception
begin
rollback;
insert into errors (msg) select concat('error ' ,inue,',',user_id,',',event_id);
end;
set autocommit = 0;
#set ue = inue;
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id)
AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id)
#AND EXISTS(SELECT 1 FROM meetup WHERE dt > NOW() AND meet_id = event_id)
AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND ifnull(participants,0) <= max_participants)
AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id)
;
select ue;
if ue = 1 then
start transaction;
INSERT INTO meetup_participation SELECT user_id, event_id,user_id, event_id;
UPDATE users SET events_participated = ifnull(events_participated,0) + 1 WHERE fb_uid=user_id = user_id;
UPDATE meetup SET participants = ifnull(participants,0) + 1 WHERE meet_id = event_id ;
commit;
end if;
SELECT ue AS response;
end //
The error table looks like this
CREATE TABLE `errors` (
`msg` varchar(2000) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
Note I am not suggesting this is a solution appropriate to your site , you need to do the research and figure out what is best for you.

SQL variable in IF exists

I can't figure out the correct way to assign query output into a variable that i could later use in an INSERT clause.
The error I get is
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET #lennuid = (select lend_id from lend where sihtpunkt=in_kuhu AND kuupaev=in_' at line 8
I've tried looking at every guide on variables in SQL but none of them could help me solve this.
Iam using the below code:
CREATE PROCEDURE proov(
in_kuhu varchar(50), in_nimi1 varchar(50), in_nimi2 varchar(50), in_adre varchar(50), in_telo varchar(20), in_email varchar(100), in_date date)
BEGIN
DECLARE viga INTEGER DEFAULT 0 ;
DECLARE lennuid INT;
START TRANSACTION;
IF exists (
SET #lennuid = (select lend_id from lend where sihtpunkt=in_kuhu AND kuupaev=in_date)) THEN
INSERT INTO broneering
(lend_id, bron_aeg, eesnim, perenimi, aadress, telefon, email)
VALUES
(lennuid, NOW(), in_nimi1, in_nimi2, in_adre, in_telo, in_email);
ELSE
set viga=1;
SELECT 'Muudatus ebaonnestus ',viga;
END IF;
IF viga=0 then
COMMIT;
select 'korras';
ELSE
select 'tagasi';
ROLLBACK;
END IF;
THEN causing the issue.
IF exists (
SET #lennuid = (select lend_id from lend where sihtpunkt=in_kuhu AND kuupaev=in_date))
BEGIN -- Instead of THEN use BEGIN , END
INSERT INTO broneering
(lend_id, bron_aeg, eesnim, perenimi, aadress, telefon, email)
VALUES
(lennuid, NOW(), in_nimi1, in_nimi2, in_adre, in_telo, in_email);
END
ELSE
BEGIN
set viga=1;
SELECT 'Muudatus ebaonnestus ',viga;
END
END IF;
You might want to use SELECT INTO:
select lend_id into #lennuid
from lend
where sihtpunkt=in_kuhu AND kuupaev=in_date;
Alternatively:
select #lennuid := lend_id
from lend
where sihtpunkt=in_kuhu AND kuupaev=in_date;
Either way works the same, then you can use that variable however you like...
In your particular example, though, the problem is actually how your exists is being used along with the set. To fix this, use the following:
IF exists (select lend_id from lend where sihtpunkt=in_kuhu AND kuupaev=in_date) THEN ...
What the problem here is, is you were setting a variable with SET inside of the EXISTS check.
Or you could do your select first as a COUNT into a numeric variable:
DECLARE cnt INTEGER;
select Count(lend_id) into #cnt
from lend
where sihtpunkt=in_kuhu
and kuupaev=in_date;
IF #cnt > 0 THEN
END IF;

declaring variable inside mysql stored procedure

we are trying to declare a variable inside mysql stored procedure that has transaction implemented in it. but it seems to be giving a syntax error :
following is the syntax of the stored procedure:
CREATE PROCEDURE `sp_MarkAppointmentRefferal`(
p_AppId bigint,
p_NewLocation bigint,
p_userId bigint,
p_ReferralReason varchar(500),
p_NewLocationName varchar(100)
)
begin
declare v_OldLocation int default 0;
set v_OldLocation = (select LocationId FROM appointments where iAppID = p_AppId limit 1 );
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
select -1;
END;
START TRANSACTION;
update table
set is_referred = 1,
referred_timestamp = now(),
referral_reason = p_ReferralReason
where iAppID = p_AppId
limit 1;
-- create a new appointment for the new referred location..
insert into appointments
(vAppName, vAppType, dAppDate, vCell, iPatID, iAppStatus, iuserid, iActive,
dInsertDate, iHSID, daily_ticket_no, LocationId, visit_id, encounter_id, ReferredFrom,ReferredOPDName, opd_name )
select vAppName, vAppType, now(), vCell, iPatID, iAppStatus, p_userId,
1, now(), iHSID, fn_GenerateNextAppointmentTicket(now(),p_NewLocation) , p_NewLocation, visit_id, encounter_id+1,
(select LocationId FROM appointments where iAppID = p_AppId limit 1),
(select OPD_Name FROM appointments where iAppID = p_AppId limit 1), p_NewLocationName
FROM appointments
where iAppID = p_AppId limit 1;
select LAST_INSERT_ID();
COMMIT;
end;
the syntax checker is saying that declare command is not valid here.
have also tried to place this inside the transaction clause and similar error shows up ..
any help is appreciated..
All declare statements should be at the top of the stored procedure body. Moving DECLARE EXIT HANDLER before the SET statement should fix the problem.

MySQL: Insert with conditional

I must perform the following situation down, but when you run got the error:
SQL Error (1064): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'INTO produto_seriais(serial_id) VALUES( SELECT id
FROM seriais WHERE serial =' at line 5
SELECT CASE WHEN (
SELECT COUNT(id) FROM seriais WHERE serial = '2020'
) > 1
THEN
(INSERT INTO produto_seriais(serial_id) VALUES(
SELECT id FROM seriais WHERE serial = '2020'
))
ELSE (
INSERT INTO seriais (serial) VALUE('2020');
SET #last_id_in_table1 = LAST_INSERT_ID();
INSERT INTO produto_seriais (serial_id) VALUES (#last_id_in_table1);
)
END;
The case is as follows:
I'll get in "serial" table by serial "X". If it already exists, unless your ID in the "produto_seriais" table. If there is (serial), I will save the same, recover your ID and save to "produto_seriais". Any suggestions for how to do this?
Important Note: This routine will run will be thousands of times each execution (10,000 or more, depending on the quantity of serial).
P.s.: Sorry for my bad english.
Try a stored procedure
DELIMITER //
CREATE PROCEDURE sp_produto_seriais(IN `p_serial_id`)
IF EXISTS (SELECT * FROM seriais WHERE serial = p_serial_id )
BEGIN
INSERT INTO produto_seriais (serial_id)
SELECT id
FROM seriais
WHERE serial = p_serial_id
END
ELSE
BEGIN
INSERT INTO seriais (serial) VALUE(p_serial_id);
INSERT INTO produto_seriais (serial_id) VALUES (LAST_INSERT_ID());
END //
DELIMITER ;
usage:
CALL sp_produto_seriais('2020')
You could use the if exists..else statement.
If exists (select * from ....)
Begin
Insert into ... Select id from table
End
Else
Begin
Insert..
End
Please fill .... with your statements. You could use the link here to convert it for MySQL.
Convert if exists for MySQL