Related
I want to add a row to a database table, but if a row exists with the same unique key I want to update the row.
For example:
INSERT INTO table_name (ID, NAME, AGE) VALUES(1, "A", 19);
Let’s say the unique key is ID, and in my Database, there is a row with ID = 1. In that case, I want to update that row with these values. Normally this gives an error.
If I use INSERT IGNORE it will ignore the error, but it still won’t update.
Use INSERT ... ON DUPLICATE KEY UPDATE
QUERY:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name="A", age=19
Check out REPLACE:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
Example:
REPLACE INTO `tablename` (`id`, `name`, `age`) VALUES (1, "A", 19)
When using batch insert use the following syntax:
INSERT INTO TABLE (id, name, age) VALUES (1, "A", 19), (2, "B", 17), (3, "C", 22)
ON DUPLICATE KEY UPDATE
name = VALUES (name),
...
Any of these solution will work regarding your question:
INSERT IGNORE INTO table (id, name, age) VALUES (1, "A", 19);
or
INSERT INTO TABLE (id, name, age) VALUES(1, "A", 19)
ON DUPLICATE KEY UPDATE NAME = "A", AGE = 19;
or
REPLACE INTO table (id, name, age) VALUES(1, "A", 19);
Try this:
INSERT INTO table (id,name,age) VALUES('1','Mohammad','21') ON DUPLICATE KEY UPDATE name='Mohammad',age='21'
Note:
Here if id is the primary key then after first insertion with id='1' every time attempt to insert id='1' will update name and age and previous name age will change.
Try this out:
INSERT INTO table (id, name, age) VALUES (1, 'A', 19) ON DUPLICATE KEY UPDATE id = id + 1;
Hope this helps.
In case that you wanted to make a non-primary fields as criteria/condition for ON DUPLICATE, you can make a UNIQUE INDEX key on that table to trigger the DUPLICATE.
ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`);
And in case you want to combine two fields to make it unique on the table, you can achieve this by adding more on the last parameter.
ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`, `age`);
Note, just make sure to delete first all the data that has the same name and age value across the other rows.
DELETE table FROM table AS a, table AS b WHERE a.id < b.id
AND a.name <=> b.name AND a.age <=> b.age;
After that, it should trigger the ON DUPLICATE event.
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name = VALUES(name), age = VALUES(age)
Just because I was here looking for this solution but for updating from another identically-structured table (in my case website test DB to live DB):
INSERT live-db.table1
SELECT *
FROM test-db.table1 t
ON DUPLICATE KEY UPDATE
ColToUpdate1 = t.ColToUpdate1,
ColToUpdate2 = t.ColToUpdate2,
...
As mentioned elsewhere, only the columns you want to update need to be included after ON DUPLICATE KEY UPDATE.
No need to list the columns in the INSERT or SELECT, though I agree it's probably better practice.
When using SQLite:
REPLACE into table (id, name, age) values(1, "A", 19)
Provided that id is the primary key. Or else it just inserts another row. See INSERT (SQLite).
In case, you want to keep old field (For ex: name). The query will be:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name=name, age=19;
In my case i created below queries but in the first query if id 1 is already exists and age is already there, after that if you create first query without age than the value of age will be none
REPLACE into table SET `id` = 1, `name` = 'A', `age` = 19
for avoiding above issue create query like below
INSERT INTO table SET `id` = '1', `name` = 'A', `age` = 19 ON DUPLICATE KEY UPDATE `id` = "1", `name` = "A",`age` = 19
may it will help you ...
Following are some of the possible approaches:
Using INSERT INTO
The INSERT statement allows you to insert one or more rows into a table
First, specify the table name and a list of comma-separated columns inside parentheses after the INSERT INTO clause.
Secondly, put a comma-separated list of values of the corresponding columns inside the parentheses following the VALUES keyword.
INSERT INTO table_name(column_name1, column_name2, column_name3) VALUES("col_value_1", "col_value_2", "col_value_3");
Using INSERT INTO with WHERE NOT EXISTS clause
INSERT INTO table_name (column_name_1, column_name_2, column_name_3)
SELECT * FROM (SELECT "col_value_1", "col_value_2","col_value_3") AS tmp_name
WHERE NOT EXISTS (
SELECT column_name2 FROM table_name WHERE column_name = "sample_name"
) LIMIT 1;
Using REPLACE INTO
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
REPLACE INTO table_name(column_name1, column_name2, column_name3) VALUES("col_value_1", "col_value_2", "col_value_3");
I want to use one form to insert into two different Microsoft sql tables. I tryed to use 2 inserts, but didnt work.
if (isset($_GET['submit'])) {
$sth = $connection->prepare("INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter','$Datum','$Verbleib','$DUTNr')");
echo "INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter',$Datum,'$Verbleib','$DUTNr')";
$sth->execute();
if($sth)
{
echo "";
}
else
{
echo sqlsrv_errors();
}
$MID = $connection->prepare("MAX(MID) as MID FROM DB.dbo.Fehler WHERE DB.dbo.Fehler.TestaufstellungID = '". $TestaufstellungID . "'");
$MID->execute();
$sth2 = $connection->prepare("INSERT INTO DB.dbo.Fehlerinfo (MID, Tester, Test, Ausfallbedingungen, Fehlerbeschreibung, Ersteller) VALUES ($MID, '$Tester','$Test','$Ausfallbedingungen','$Fehlerbeschreibung','$Ersteller')");
$sth2->execute();
To understand MID is the Primary key of table Fehler and ist the foreign key in the second table Fehlerinfo
Thats why i have the select work around to get the last MID and want to save it in a variable $MID to insert it into the second table.
Is there a smarter solution possible?
As I mentioned in the comments, generally the better way is to do the insert in one batch. This is very over simplified, however, should put you in the right direction. Normally you would likely be passing the values for the Foreign Table in a Table Value Parameter (due to the Many to One relationship) and would encapsulate the entire thing in a TRY...CATCH and possibly a stored procedure.
I can't write this in PHP, as my knowledge of it is rudimentary, but this should get you on the right path to understanding:
USE Sandbox;
--Couple of sample tables
CREATE TABLE dbo.PrimaryTable (SomeID int IDENTITY(1,1),
SomeString varchar(10),
CONSTRAINT PK_PTID PRIMARY KEY NONCLUSTERED (SomeID));
CREATE TABLE dbo.ForeignTable (AnotherID int IDENTITY(1,1),
ForeignID int,
AnotherString varchar(10),
CONSTRAINT PK_FTID PRIMARY KEY NONCLUSTERED(AnotherID),
CONSTRAINT FK_FTPT FOREIGN KEY (ForeignID)
REFERENCES dbo.PrimaryTable(SomeID));
GO
--single batch example
--Declare input parameters and give some values
--These would be the values coming from your application
DECLARE #SomeString varchar(10) = 'abc',
#AnotherString varchar(10) = 'def';
--Create a temp table or variable for the output of the ID
DECLARE #ID table (ID int);
--Insert the data and get the ID at the same time:
INSERT INTO dbo.PrimaryTable (SomeString)
OUTPUT inserted.SomeID
INTO #ID
SELECT #SomeString;
--#ID now has the inserted ID(s)
--Use it to insert into the other table
INSERT INTO dbo.ForeignTable (ForeignID,AnotherString)
SELECT ID,
#AnotherString
FROM #ID;
GO
--Check the data:
SELECT *
FROM dbo.PrimaryTable PT
JOIN dbo.ForeignTable FT ON PT.SomeID = FT.ForeignID;
GO
--Clean up
DROP TABLE dbo.ForeignTable;
DROP TABLE dbo.PrimaryTable;
As i mentioned the answer how it works for me fine atm.
if (isset($_GET['submit'])) {
$failInsert = ("INSERT INTO DB.dbo.Fehler (QualiID, TestaufstellungID, ModulinfoID, failAfter, Datum, Verbleib, DUTNr) VALUES ($QualiID, $TestaufstellungID,$ModulinfoID,'$failAfter','$Datum','$Verbleib','$DUTNr')");
$failInsert .= ("INSERT INTO DB.dbo.Fehlerinfo (MID, Tester, Test, Ausfallbedingungen, Fehlerbeschreibung, Ersteller) VALUES (NULL, '$Tester','$Test','$Ausfallbedingungen','$Fehlerbeschreibung','$Ersteller')");
$failInsert .= ("UPDATE DB.dbo.Fehlerinfo SET DB.dbo.Fehlerinfo.MID = i.MID FROM (SELECT MAX(MID)as MID FROM DB.dbo.Fehler) i WHERE DB.dbo.Fehlerinfo.TestID = ( SELECT MAX(TestID) as TestID FROM DB.dbo.Fehlerinfo)");
$sth = $connection->prepare($failInsert);
$sth->execute();
}
I want to add a row to a database table, but if a row exists with the same unique key I want to update the row.
For example:
INSERT INTO table_name (ID, NAME, AGE) VALUES(1, "A", 19);
Let’s say the unique key is ID, and in my Database, there is a row with ID = 1. In that case, I want to update that row with these values. Normally this gives an error.
If I use INSERT IGNORE it will ignore the error, but it still won’t update.
Use INSERT ... ON DUPLICATE KEY UPDATE
QUERY:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name="A", age=19
Check out REPLACE:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
Example:
REPLACE INTO `tablename` (`id`, `name`, `age`) VALUES (1, "A", 19)
When using batch insert use the following syntax:
INSERT INTO TABLE (id, name, age) VALUES (1, "A", 19), (2, "B", 17), (3, "C", 22)
ON DUPLICATE KEY UPDATE
name = VALUES (name),
...
Any of these solution will work regarding your question:
INSERT IGNORE INTO table (id, name, age) VALUES (1, "A", 19);
or
INSERT INTO TABLE (id, name, age) VALUES(1, "A", 19)
ON DUPLICATE KEY UPDATE NAME = "A", AGE = 19;
or
REPLACE INTO table (id, name, age) VALUES(1, "A", 19);
Try this:
INSERT INTO table (id,name,age) VALUES('1','Mohammad','21') ON DUPLICATE KEY UPDATE name='Mohammad',age='21'
Note:
Here if id is the primary key then after first insertion with id='1' every time attempt to insert id='1' will update name and age and previous name age will change.
Try this out:
INSERT INTO table (id, name, age) VALUES (1, 'A', 19) ON DUPLICATE KEY UPDATE id = id + 1;
Hope this helps.
In case that you wanted to make a non-primary fields as criteria/condition for ON DUPLICATE, you can make a UNIQUE INDEX key on that table to trigger the DUPLICATE.
ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`);
And in case you want to combine two fields to make it unique on the table, you can achieve this by adding more on the last parameter.
ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`, `age`);
Note, just make sure to delete first all the data that has the same name and age value across the other rows.
DELETE table FROM table AS a, table AS b WHERE a.id < b.id
AND a.name <=> b.name AND a.age <=> b.age;
After that, it should trigger the ON DUPLICATE event.
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name = VALUES(name), age = VALUES(age)
Just because I was here looking for this solution but for updating from another identically-structured table (in my case website test DB to live DB):
INSERT live-db.table1
SELECT *
FROM test-db.table1 t
ON DUPLICATE KEY UPDATE
ColToUpdate1 = t.ColToUpdate1,
ColToUpdate2 = t.ColToUpdate2,
...
As mentioned elsewhere, only the columns you want to update need to be included after ON DUPLICATE KEY UPDATE.
No need to list the columns in the INSERT or SELECT, though I agree it's probably better practice.
When using SQLite:
REPLACE into table (id, name, age) values(1, "A", 19)
Provided that id is the primary key. Or else it just inserts another row. See INSERT (SQLite).
In case, you want to keep old field (For ex: name). The query will be:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name=name, age=19;
In my case i created below queries but in the first query if id 1 is already exists and age is already there, after that if you create first query without age than the value of age will be none
REPLACE into table SET `id` = 1, `name` = 'A', `age` = 19
for avoiding above issue create query like below
INSERT INTO table SET `id` = '1', `name` = 'A', `age` = 19 ON DUPLICATE KEY UPDATE `id` = "1", `name` = "A",`age` = 19
may it will help you ...
Following are some of the possible approaches:
Using INSERT INTO
The INSERT statement allows you to insert one or more rows into a table
First, specify the table name and a list of comma-separated columns inside parentheses after the INSERT INTO clause.
Secondly, put a comma-separated list of values of the corresponding columns inside the parentheses following the VALUES keyword.
INSERT INTO table_name(column_name1, column_name2, column_name3) VALUES("col_value_1", "col_value_2", "col_value_3");
Using INSERT INTO with WHERE NOT EXISTS clause
INSERT INTO table_name (column_name_1, column_name_2, column_name_3)
SELECT * FROM (SELECT "col_value_1", "col_value_2","col_value_3") AS tmp_name
WHERE NOT EXISTS (
SELECT column_name2 FROM table_name WHERE column_name = "sample_name"
) LIMIT 1;
Using REPLACE INTO
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
REPLACE INTO table_name(column_name1, column_name2, column_name3) VALUES("col_value_1", "col_value_2", "col_value_3");
I want to add a row to a database table, but if a row exists with the same unique key I want to update the row.
For example:
INSERT INTO table_name (ID, NAME, AGE) VALUES(1, "A", 19);
Let’s say the unique key is ID, and in my Database, there is a row with ID = 1. In that case, I want to update that row with these values. Normally this gives an error.
If I use INSERT IGNORE it will ignore the error, but it still won’t update.
Use INSERT ... ON DUPLICATE KEY UPDATE
QUERY:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name="A", age=19
Check out REPLACE:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
Example:
REPLACE INTO `tablename` (`id`, `name`, `age`) VALUES (1, "A", 19)
When using batch insert use the following syntax:
INSERT INTO TABLE (id, name, age) VALUES (1, "A", 19), (2, "B", 17), (3, "C", 22)
ON DUPLICATE KEY UPDATE
name = VALUES (name),
...
Any of these solution will work regarding your question:
INSERT IGNORE INTO table (id, name, age) VALUES (1, "A", 19);
or
INSERT INTO TABLE (id, name, age) VALUES(1, "A", 19)
ON DUPLICATE KEY UPDATE NAME = "A", AGE = 19;
or
REPLACE INTO table (id, name, age) VALUES(1, "A", 19);
Try this:
INSERT INTO table (id,name,age) VALUES('1','Mohammad','21') ON DUPLICATE KEY UPDATE name='Mohammad',age='21'
Note:
Here if id is the primary key then after first insertion with id='1' every time attempt to insert id='1' will update name and age and previous name age will change.
Try this out:
INSERT INTO table (id, name, age) VALUES (1, 'A', 19) ON DUPLICATE KEY UPDATE id = id + 1;
Hope this helps.
In case that you wanted to make a non-primary fields as criteria/condition for ON DUPLICATE, you can make a UNIQUE INDEX key on that table to trigger the DUPLICATE.
ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`);
And in case you want to combine two fields to make it unique on the table, you can achieve this by adding more on the last parameter.
ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`, `age`);
Note, just make sure to delete first all the data that has the same name and age value across the other rows.
DELETE table FROM table AS a, table AS b WHERE a.id < b.id
AND a.name <=> b.name AND a.age <=> b.age;
After that, it should trigger the ON DUPLICATE event.
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name = VALUES(name), age = VALUES(age)
Just because I was here looking for this solution but for updating from another identically-structured table (in my case website test DB to live DB):
INSERT live-db.table1
SELECT *
FROM test-db.table1 t
ON DUPLICATE KEY UPDATE
ColToUpdate1 = t.ColToUpdate1,
ColToUpdate2 = t.ColToUpdate2,
...
As mentioned elsewhere, only the columns you want to update need to be included after ON DUPLICATE KEY UPDATE.
No need to list the columns in the INSERT or SELECT, though I agree it's probably better practice.
When using SQLite:
REPLACE into table (id, name, age) values(1, "A", 19)
Provided that id is the primary key. Or else it just inserts another row. See INSERT (SQLite).
In case, you want to keep old field (For ex: name). The query will be:
INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE
name=name, age=19;
In my case i created below queries but in the first query if id 1 is already exists and age is already there, after that if you create first query without age than the value of age will be none
REPLACE into table SET `id` = 1, `name` = 'A', `age` = 19
for avoiding above issue create query like below
INSERT INTO table SET `id` = '1', `name` = 'A', `age` = 19 ON DUPLICATE KEY UPDATE `id` = "1", `name` = "A",`age` = 19
may it will help you ...
Following are some of the possible approaches:
Using INSERT INTO
The INSERT statement allows you to insert one or more rows into a table
First, specify the table name and a list of comma-separated columns inside parentheses after the INSERT INTO clause.
Secondly, put a comma-separated list of values of the corresponding columns inside the parentheses following the VALUES keyword.
INSERT INTO table_name(column_name1, column_name2, column_name3) VALUES("col_value_1", "col_value_2", "col_value_3");
Using INSERT INTO with WHERE NOT EXISTS clause
INSERT INTO table_name (column_name_1, column_name_2, column_name_3)
SELECT * FROM (SELECT "col_value_1", "col_value_2","col_value_3") AS tmp_name
WHERE NOT EXISTS (
SELECT column_name2 FROM table_name WHERE column_name = "sample_name"
) LIMIT 1;
Using REPLACE INTO
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
REPLACE INTO table_name(column_name1, column_name2, column_name3) VALUES("col_value_1", "col_value_2", "col_value_3");
I am wondering how to store the value of a primary key, auto-incremented by "DEFAULT" so that I can insert it as a value in another table row.
So far I have:
$sql = "INSERT INTO sales (
sale_id,
sale_amt,
sale_date)
VALUES (
DEFAULT, # <--- how to store the resulting value of this?
'$amt',
'$date'
)";
I need the specific value created by "DEFAULT" to be stored, so that I can insert it into another table's row. How do I do this with either PHP or MySQL?
You don't. You use last_insert_id() to retrieve it AFTER you've performed the first insert.
INSERT INTO foo (bar) VALUES (baz)
SELECT #id := last_insert_id();
INSERT INTO other (id, parent) VALUES (null, #id)
INSERT INTO yetanother (id, parent) VALUES (null, #id)
Note that last_insert_id() is not smart and will return the id of the LAST insert you did. If you do two inserts, and then try to get the ids, you'll get the id of the second (last) insert.
MySQL:
You can find this in MySQL by using the LAST_INSERT_ID() function, as the last insert ID will be returned that you inserted for an AUTO_INCREMENT value.
$sql = "INSERT INTO sales (
sale_id,
sale_amt,
sale_date)
VALUES (
DEFAULT, # <--- how to store the resulting value of this?
'$amt',
'$date'
)";
sql2 = "INSERT INTO records (
sale_id,
customer_name,
other_info)
VALUES (
LAST_INSERT_ID(), <-------- correct sales_id
'$name',
'$info');