Mysql procedure to insert data from file - mysql

I have an application that save data into a table , say my_table.
my_table
id | name | salary
this is a data entry application and not having a centralized database.Once all data entries complete, I have to merge the databases. My plan is to export insert statements from say DB2 and append it to DB1. So i wrote a procedure as follows:
CREATE PROCEDURE insertToTable
DECLARE max_id INT DEFAULT 1
BEGIN
SELECT MAX(id) INTO max_id FROM my_table
INSERT INTO table(id,name,salary) VALUES(max_id+1,'tom',1000);
INSERT INTO table(id,name,salary) VALUES(max_id+1,'john',1500);
....//a lot of statements
END
here i just increment id of DB2 by the max(id) of DB1 to avoid conflict.It works fine.
But some databases have large number of records.I could get these insert statements with 'max_id' variable in position.Then can I execute these 'insert' statements from file inside that procedure. Or is there any better solution..

Make "Id" column auto incremental by adding sequence.
Then create a trigger that increment upon insert.

I think i need this trigger:
CREATE TRIGGER insert_test BEFORE INSERT ON table my_table
FOR EACH ROW
BEGIN
SET #max_id = select max(id) from my_table;
IF NEW.id >= #max_id THEN
NEW.id = #max_id + 1;
END IF;
END;
Thanks for your suggestion.

Related

MySQL Get row data from Update query with LIMIT via stored procedure

I have a query which updates multiple rows in a table with a variable LIMIT. I need to get data from the updated rows so I know which exact rows got affected. I wrote this simple procedure:
DELIMITER $$
CREATE PROCEDURE select_update(IN myId INT, IN myAttr VARCHAR(10), IN myAmount MEDIUMINT)
begin
SELECT data FROM mytable WHERE id IS NULL AND attr = myAttr LIMIT myAmount;
UPDATE mytable SET id = myId WHERE id IS NULL AND attr = myAttr LIMIT myAmount;
end$$
DELIMITER ;
Will this SELECT statement always return the exact same rows that the UPDATE statement affects? Is it possible for another user to execute a query while this procedure is running and thus to possibly change the affected rows between the SELECT and UPDATE?
Create a temporary table to hold the primary keys of the rows to be updated.
CREATE PROCEDURE select_update(IN myId INT, IN myAttr VARCHAR(10), IN myAmount MEDIUMINT)
begin
CREATE TEMPORARY TABLE temp_mytable AS
SELECT pk FROM mytable WHERE id IS NULL AND attr = myAttr LIMIT myamnt;
UPDATE mytable JOIN temp_mytable USING (pk)
SET mytable.id = myId;
SELECT mytable.data
FROM mytable JOIN temp_mytable USING (pk);
end$$

MySQL - Using SELECT for IF statement condition in stored procedure

I want to execute, in a stored procedure, a certain set of statements if, in table my_table there is exactly one row with value value in column column_name. I have tried the following, but I get a syntax error:
IF ((SELECT COUNT(*) FROM my_table WHERE column_name = value) = 1) THEN
BEGIN
END;
END IF;
For context: In my procedure I create a temporary table at some point, where I store a list of values. Then later on in the procedure, I want to check if a given value is present in that temporary table.
I think you might be better to structure it more like this
BEGIN
DECLARE myCOUNT INTEGER;
SELECT COUNT(*)
INTO myCount
FROM my_table
WHERE column_name=value;
IF (myCount = 1) THEN
-- do stuff
END IF;
END;
I'm not sure what you are trying to do, but I'll guess an "upsert" -- update a record if it exists, otherwise insert a new record.
In any case, if you are trying to ensure that name is unique in my_table, then this is not the right approach at all. Instead, declare a unique index/constraint so the database ensures the data integrity:
create unique index unq_my_table_name on my_table(name);
You can then use insert . . . on duplicate key update to modify the records in the database.

How to save records from one table to another table using stored procedure in mysql?

I have tried, but I don't know how to do this.
I want to migrate records from one table into another table using a stored procedure. I have started with a simple procedure (not sure whether it is right or wrong) to print the records based on some condition. Here is the code with which i have tried:
CREATE PROCEDURE curdemo()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a VARCHARCHAR(16);
DECLARE cur1 CURSOR FOR SELECT user_name FROM discovery_configuration;
OPEN cur1;
REPEAT
FETCH cur1 INTO a;
IF a!=' ' THEN
select a;
END IF;
END REPEAT;
CLOSE cur1;
END;
I need a stored procedure to migrate those records to another table if user_name column is empty. Can anyone guide me?
Why does it have to be a stored procedure?
You can copy the records in one query, then delete them with another.
Copy to another table where user_name is empty:
INSERT INTO other_table (id, user_name, other)
SELECT (id, user_name, other)
FROM discovery_configuration
WHERE user_name IS NULL OR TRIM(user_name) = '';
Then, after you have copied these records, delete from original table:
DELETE FROM discovery_configuration WHERE id IN (SELECT id FROM other_table);
Are you inserting all the columns or only user name? if you are inserting all the columns into the another table you should be getting all the columns into the cursor and then insert into the table.. and leave this..based on the info provided above i got that you would like to migrate the data from one table to another table if the username column is null...right?
then you have an easy way to do that.
INSERT INTO A (COUMNS DETAILS) SELECT COLUMNS FROM B WHERE B.USERNAME = ' ';
Try this and let me know..!!
-Rajesh Uddem
How about:
Insert userName into newTable
Select userName from discovery_configuration where cur1 != ' '

want to write trigger for two different databases in Mysql

Is there any way to create triggers on two different databases in Mysql? my requirement is like:-
database: test1 -> table: tmp1
database: test2 -> table: tmp2
now I have to use trigger on test1 insert operation happens on tmp1 a value has to be inserted into tmp2 of test2 database. And also vice a verse.
i.e. one more trigger on tmp2 table of test2 database, if insert into tmp2 then inserted into tmp1 table of test1 database.
I have tried to write the trigger on both but I think it will goes into loop to insert each other tables.
DELIMITER $$
CREATE TRIGGER trigger_ad_t1 AFTER insert ON `test1`.tmp1
FOR EACH ROW
Begin
INSERT INTO `test2`.tmp2 VALUES (NEW.employeeNumber,New.fname,New.lname)
END$$
DELIMITER ;
same type of trigger written for insert into tmp1 after insert into tmp2 table.
One more thing I have tested this trigger on my local pc which has mysql 5.1.63 but when I am trying this trigger on my testing server which has mysql 5.0.45 then it gives me syntax error(1064). Don't know what is the problem?
UPDATE:
Can anybody help me to get rid of it.
Thanks
Use fully qualified table names in your trigger.
I.e.
db1.test1.* and d2.test2.*
P.S. After looking at your SQL one more time I realised that you ARE doing the above already.
Edit: Comment field is to restrictive to post code, so here is how you prevent the endless insert loop (assuming employeeNumber is unique key):
Edited code:
IF NOT EXISTS(SELECT employeeNumber FROM otherDB.otherTable WHERE employeeNumber = NEW.employeeNumber) THEN
INSERT INTO otherDB.otherTable VALUES (NEW.employeeNumber,New.fname,New.lname)
END IF;
Correction was needed in the code provided originally:
... EXISTS(SELECT * FROM otherDB.otherTable ...) is replaced with
... EXISTS(SELECT employeeNumber FROM otherDB.otherTable ...)
The reason being that the first query will always return true because the inner query SELECT * FROM ... always returns one record containing the number of results =>
EXISTS(SELECT * FROM ...) is always true

Getting "There is already an object named" while creating a temp table

Msg 2714, Level 16, State 1, Procedure QOTD, Line 12 There is already an object named '#tmpID3' in the database.
ALTER PROCEDURE QOTD (#source INT) AS
BEGIN
IF #source = 1
SELECT ID INTO #tmpID3 FROM tbl1
ELSE
SELECT ID INTO #tmpID3 FROM tbl2
SELECT ID FROM #tmpID3
DROP TABLE #tmpID3
END
Msg 2714, Level 16, State 1, Procedure QOTD, Line 7 There is already an object named '#tmpID3' in the database. – jesvin Nov 19 at 5:37
while adding this i am getting the error
You are seeing a parser error when trying to create your procedure. The temp table does not yet exist but the parser thinks it does.
Have a look at my answer to this question: There is already an object named '#columntable' in the database.
I originally thought, as others who have answered your question, that you would get this error because you were not explicitly dropping the temp table at the end of you procedure. However, as crokusek first pointed out in his comment:
local temp tables are auto deleted at the end of the procedure in
which they are created
So I tried creating your procedure in my SQL Server 2008 instance and got the same error.
Changing the procedure to use different temp table names, as shown below, avoids the problem and proves the temp tables are dropped after the procedure ends.
CREATE TABLE tbl1 ( ID INT )
GO
CREATE TABLE tbl2 ( ID INT )
GO
INSERT INTO tbl1(ID) VALUES (1),(2),(3)
INSERT INTO tbl2(ID) VALUES (4),(5),(6)
GO
CREATE PROCEDURE QOTD ( #source INT )
AS
SET NOCOUNT ON
BEGIN
IF #source = 1
BEGIN
SELECT ID INTO #tmpID13 FROM tbl1
SELECT ID FROM #tmpID13
END
ELSE
BEGIN
SELECT ID INTO #tmpID23 FROM tbl2
SELECT ID FROM #tmpID23
END
END
GO
EXEC QOTD 1
EXEC QOTD 2
Output:
ID
-----------
1
2
3
ID
-----------
4
5
6
It's already there. If you're creating this table as part of a regularly running script, add a DROP TABLE #tmpID3 at the start.
temp tables are single threaded (ie the server can do nothing else while creating it). If you're using it often, consider table variables instead.
Start procedure QOTD with:
Drop Table #tmpID3
Objects have to have unique names across the database. SQL Server handles the uniqueness of temporary table names. However, if there are supplementary objects, such as separately created primary keys, it is possible for collisions to occur when two users attempt to create the table at the same time.
The error message you cite has an object with ID in its name, so I am guessing this is the situation you find yourself in. Andy Novick has written a note on this topic, explaining why it might happen and giving a couple of workarounds. Check it out.
Have a look at Check If Temporary Table Exists
EDIT How to check for the temp table and drop it if it exists
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL
BEGIN
DROP TABLE #TEMP
END
EDIT 2 It would seem that the 2 select into's are conflicting with each other. Creating the table before hand works though. Something like
ALTER PROCEDURE QOTD (#source INT)
AS
BEGIN
IF OBJECT_ID('tempdb..#tmpID3') IS NOT NULL
BEGIN
DROP TABLE #tmpID3
END
CREATE TABLE #tmpID3(
ID INT
)
IF #source = 1
BEGIN
INSERT INTO #tmpID3 SELECT ID FROM tbl1
END
ELSE
BEGIN
INSERT INTO #tmpID3 SELECT ID FROM tbl2
END
SELECT ID FROM #tmpID3
DROP TABLE #tmpID3
END
EDIT 3 the temp table is not required in this instance. A simple if will do
Something like
ALTER PROCEDURE QOTD (#source INT)
AS
BEGIN
IF #source = 1
BEGIN
SELECT ID FROM tbl1
END
ELSE
BEGIN
SELECT ID FROM tbl2
END
END
I had exactly the same issue, see my answer here:There is already an object named '#columntable' in the database
The solution in this case seems to be to first create the table, then add the rows. This way the parser does not complain (as this is a known parser issue).
ALTER PROCEDURE QOTD (#source INT) AS
BEGIN
-- Create the table without having to declare any column types or sizes
SELECT TOP 0 ID INTO #tmpID3 FROM tbl1
-- Prevent IDENTITY_INSERT error
SET IDENTITY_INSERT #tmpID3 ON
-- Add the actual rows required
IF #source = 1
INSERT INTO INTO #tmpID3 (ID) SELECT ID FROM tbl1
ELSE
INSERT INTO INTO #tmpID3 (ID) SELECT ID FROM tbl2
SET IDENTITY_INSERT #tmpID3 OFF
SELECT ID FROM #tmpID3
DROP TABLE #tmpID3
END