I have a trigger on a table, it's basically this
ALTER TRIGGER xx
FOR UPDATE,DELETE,INSERT
AS
DELETE FROM other WHERE id in (SELECT id from deleted)
DELETE FROM other WHERE id in (SELECT id from inserted)
INSERT INTO other() VALUES() WHERE id in (SELECT id from inserted)
GO
It runs extremely slow when it does the insert (20 seconds). The deletes are fast. Playing around I tried doing this instead:
ALTER TRIGER xx
FOR UPDATE,DELETE,INSERT
AS
DECLARE #tinserted TABLE ( id int)
INSERT INTO #tinserted select id from inserted;
DELETE FROM other WHERE id in (SELECT id from deleted)
DELETE FROM other WHERE id in (SELECT id from inserted)
INSERT INTO other() VALUES() WHERE id in (SELECT id from #tinserted)
GO
By using a table variable it now runs instantly (under 1 second).
I'm not sure why though. Is there any reason why changing to a table variable would make such a difference?
Not sure why you'd need the WHERE clause at all for the INSERT operation.
INSERT INTO other(column1, column2, ...)
SELECT column1, column2, ...
FROM inserted;
Related
Hi i need to Mysql Auto create, update, delete table 2 from table 1
I have table 1 which column is:
id, title, category, sku, brand, price, last_update
And i have table 2 which column is:
id, title, sku, brand, code1, code2
What i need to if table a insert new value or update or delete will affect to table 2, how can i do that ?
I try this :
INSERT INTO table2 (title, sku, brand)
SELECT title, sku, brand
FROM table1
But this not good idea because when i run agaain sql much duplicate i have and i can not update it, please tell me how do that.
Iam using trigger to solved my problem :
CREATE TRIGGER table1insert after INSERT ON table1
FOR EACH ROW BEGIN
INSERT INTO table2 SET
title = NEW.title, sku=New.sku, brand=NEW.brand
ON DUPLICATE KEY UPDATE sku=New.sku;
END$$
and i make one again trigger if table 1 delete so table 2 deleted too.
CREATE TRIGGER table1delete after DELETE ON table1
FOR EACH ROW BEGIN
DELETE FROM table2
WHERE sku=old.sku;
END$$
maybe this can help everyone need it
I'm inserting some_data (a unique key column), and then using the resulting user_id (the primary key auto-increment column) in a separate statement (not shown)
INSERT IGNORE INTO users (some_data) VALUES ('test');
SELECT LAST_INSERT_ID(); <--- I do stuff with this.
But, of course, if some_data already exists (happens very frequently), LAST_INSERT_ID() returns 0. What is the best way to get the user_id based on the unique key some_data, in this case? Of course I can do a separate WHERE query, but not sure that is the most efficient.
From http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
INSERT INTO users ( id, some_col ) VALUES (n,some_val)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), some_col=some_val;
Not an ignore but might do the job?
Edit:
To be clear, this will update some_col with some_val and then set the LAST_INSERT_ID to return the id of the duplicate row.
It could just as well be this if you didn't want to update any data on the duplicate but just set the LAST_INSERT_ID() call to give you what you want:
INSERT INTO users ( user_name ) VALUES ( 'bobloblaw' )
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID( id );
Edit 2:
Use a proc to do the work and get back the id
DELIMITER $$
CREATE PROCEDURE insert_test( val1 varchar(10), val2 varchar(10) )
BEGIN
INSERT INTO test.test_table ( col1, col2 ) SELECT val1, val2 FROM ( select 1 ) as a
WHERE NOT EXISTS (
select 1 from test.test_table t where t.col1 = val1
);
SELECT id FROM test.test_table where col1 = val1;
END $$
DELIMITER ;
I've seen lots of questions with similar headlines or interest but different from what I am looking for.
I have a table with some data in it already, with an id column. I want the id's of the data already in the table, a couple thousand rows, to remain the same. I want to INSERT different data from another table, which also includes id's - just over 92,000 rows in this set -- and I need these id's to change to some other non-existing ID so as not to overwrite or displace the already existing data.
Is this possible? Is there some kind of increment I can do upon INSERT?
I tried an INSERT IGNORE statement but it displaced the data already there.
Any advice on what to try?
If id in your first table is an auto_increment column then you can just omit it
INSERT INTO table1 (column2, column3, column4, ...) -- id is omitted
SELECT column2, column3, column4, ... -- id is also omitted
FROM table2
If it's not the case, and assuming that it's a one-time operation, you can try to assign new ids in a following way
INSERT INTO table1 (id, column2, column3, column4, ...)
SELECT t.max_id + s.id, s.column2, s.column3, s.column4, ...
FROM
(
SELECT #n := #n + 1 id, column1
FROM table2 CROSS JOIN (SELECT #n := 0) i
ORDER BY id
) s JOIN
(
SELECT MAX(id) max_id
FROM table1
) t
Here is SQLFiddle demo
To start with an AUTO_INCREMENT value other than 1, set that value with CREATE TABLE or ALTER TABLE, like this:
mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;
I am trying to populate a products table on MySQL with latest products, which are retrieved and stored in products_temp table.
So the method for this is straight forward, simply doing an INSERT to products from products_temp, as such:
INSERT INTO products ( select products_temp.* FROM products_temp )
Problem is, it results in a duplicate primary key error, because of the id from products_temp clashing with the id in products.
Can someone tell me how to fix this please?
I tried declaring the fields in the select statement without the id, but that results in "Column count doesn't match value count at row 1"
Any help would be appreciated.
Thanks!
You'll need to declare the columns except the ID on both the INSERT and the SELECT, since the number of fields need to match, and id (as you noticed) can't be inserted as is into the destination table.
INSERT INTO DestTable (field1, field2, field3)
SELECT field1, field2, field3 FROM SourceTable;
An SQLfiddle to test with.
EDIT: You could do it in a bit more hacky way to simplify the insert. You can create a trigger that simply forces the primary key to NULL on insert.
CREATE TRIGGER t_DT BEFORE INSERT ON DestTable
FOR EACH ROW
SET NEW.id = NULL;
then a copy from table to table can be done as simply;
INSERT INTO DestTable SELECT * FROM SourceTable;
Another SQLfiddle.
How about something like:
INSERT INTO products
(
select products_temp.* FROM products_temp
where key not in (select key from products)
)
(using SS2008) Within a sql server database, I'd like to copy all the data of one client for a new client. In other words, generate exact duplicates of all records that pertain to client #1, except now the client ID field of the new records refer to client #2. This is all inside the same database.
Normally I would do this with a series of INSERT commands on the relevant tables selecting the client #1 records. However, some of the tables have autonumber ID columns, and these IDs are referenced as foreign keys in child tables. So when generating the child table records, I'd need to know and refer to the newly created autonumber Ids.
What is the cleanest way to go about this? Can it be done with SQL Server replication? My knowledge of SQL Server is pretty moderate.
I would do something like this:
-- Set up a placeholder for the new id
DECLARE #NewID INT;
-- INSERT parent record
INSERT INTO myTable (field1, field2)
SELECT field1, field2 FROM myTable WHERE ID = 1
-- Get the new ID
SET #NewID = (SELECT SCOPE_IDENTITY());
-- Insert child records with new id
INSERT INTO OtherTable (fkid, field1, field2)
SELECT #NewID, field1, field2 FROM OtherTable WHERE ID = 1
Now if we need to deal with thousands of records, this could work:
-- Add a new column in the database to manage where the record came from
ALTER TABLE myTable ADD ParentID int NULL
-- INSERT parent record
INSERT INTO myTable (field1, field2, ParentID)
SELECT
field1
, field2
, ID
FROM myTable
WHERE SomeCondition IS True
-- Insert child records with new id
INSERT INTO OtherTable (fkid, field1, field2)
SELECT
myTable.ID
, OtherTable.field1
, OtherTable.field2
FROM
OtherTable
INNER JOIN myTable ON OtherTable.FKID = myTable.ParentID
-- Once unneeded, drop the temporary column
-- ALTER TABLE myTable DROP COLUMN ParentID