I got a situation that need to insert only if record does not exist. Normally, I'm going to use 2 queries with conditions like this:
SELECT FROM TABLE ->
IF RECORD NOT FOUND THEN -> INSERT INTO TABLE
ELSE -> DO NOTHING
I feel my solution is not a good one. How can I achieve the same thing with just a single query? For example:
SELECT * from user where status='A' AND name='Lewis'
IF RECORD NOT FOUND THEN
INSERT INTO user(status,name) VALUES('F','Lewis');
You mean something like:
BEGIN
IF NOT EXISTS (SELECT * from user where status='A' AND name='Lewis')
BEGIN
INSERT INTO user (status, name)
VALUES('F','Lewis')
END
END
This works in SQL Server, and should be possible in MySQL as well.
Edit:
Apparently it's not working in MySQL (just testd). However, you could use INSERT IGNORE:
INSERT IGNORE INTO user2 (status, name)
VALUES('F','Lewis');
Note that that would only work if you have a unique or primary key.
Another way could be to have the same unique or primary key, and then use:
INSERT IGNORE INTO user2 (status, name)
VALUES('F','Lewis')
ON DUPLICATE KEY UPDATE status=status;
This avoids ending up with other errors being ignored, and only ignores the duplicate key warning.
Related
Hi i am trying to insert data into another table and i would like to skip duplicate record in the target table. I have used the following mysql query.
insert into adggtnz.`reg02_maininfo`(farmermobile,farmername,farmergender,origin)
select * from (SELECT mobile_no,name,sex,'EADD' FROM EADD.farmer)
as tmp where not exists (select farmermobile from adggeth.`reg02_maininfo` where farmermobile = tmp.mobile_no)
The problem is that when there is a duplicate the query does not completely run how can i avoid the following error
16:09:03 insert into adggtnz.`reg02_maininfo`(farmermobile,farmername,farmergender,origin) select * from (SELECT mobile_no,name,sex,'EADD' FROM EADD.farmer) as tmp where not exists (select farmermobile from adggeth.`reg02_maininfo` where farmermobile = tmp.mobile_no) Error Code: 1062. Duplicate entry '0724961552' for key 'PRIMARY' 0.828 sec
Please help me modify my query
If you want to avoid duplicate entries, you never EVER query first to see if a record exists. You place a unique constraint and use INSERT IGNORE or INSERT INTO ... ON DUPLICATE KEY UPDATE.
The problem with first approach is that you can (and will) get false positives.
In your particular case, the fix is quite easy. You need to add IGNORE after INSERT. That will skip the record if duplicate and continue onto the next one.
INSERT IGNORE INTO adggtnz.`reg02_maininfo`(farmermobile,farmername,farmergender,origin)
SELECT mobile_no, name, sex, 'EADD' FROM EADD.farmer
Get the select query which initially checks the farmer mobile number in reg02_maininfo and then insert into reg02_maininfo.
insert into adggtnz.`reg02_maininfo`(farmermobile,farmername,farmergender,origin)
SELECT mobile_no,name,sex,'EADD' FROM EADD.farmer where mobile_no not in
(select farmermobile from adggeth.`reg02_maininfo`)
I need to create a query to insert some records, the record must be unique. If it exists I need the recorded ID else if it doesnt exist I want insert it and get the new ID. I wrote that query but it doesnt work.
SELECT id FROM tags WHERE slug = 'category_x'
WHERE NO EXISTS (INSERT INTO tags('name', 'slug') VALUES('Category X','category_x'));
It's called UPSERT (i.e. UPdate or inSERT).
INSERT INTO tags
('name', 'slug')
VALUES('Category X','category_x')
ON DUPLICATE KEY UPDATE
'slug' = 'category_x'
MySql Reference: 13.2.5.3. INSERT ... ON DUPLICATE KEY UPDATE Syntax
Try something like...
IF (NOT EXISTS (SELECT id FROM tags WHERE slug = 'category_x'))
BEGIN
INSERT INTO tags('name', 'slug') VALUES('Category X','category_x');
END
ELSE
BEGIN
SELECT id FROM tags WHERE slug = 'category_x'
END
But you can leave the ELSE part and SELECT the id, this way the query will always return the id, irrespective of the insert...
MySQL has nice REPLACE. It is easy to use and remember it's syntax as same as INSERT.
in you case, just run following query.
REPLACE INTO tags('name', 'slug') VALUES('Category X','category_x')
It acts like INSERT when no unique constraint violation. If duplicated value found on PK or UNIQUE key, then other columns will be UPDATED with given values. It is done by DELETE duplicated record and INSERT new record.
I have a simple table like this
CREATE TABLE authid(
id INT NOT NULL AUTO_INCREMENT,
authid VARCHAR(128) NOT NULL UNIQUE,
PRIMARY KEY(id)
);
Now if I insert a value with
INSERT INTO authid(authid) VALUES('test');
It will work fine and return the inserted id the first time, but if I do it again when the authid already exists (notice that we have authid marked as UNIQUE) it will return an error.
Is there a way achieve this this in one SQL statement: Insert it, get the id and if it already exists, still get the id.
Take a look at this: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
If you're using MySQL 5.0 or higher you can use the "INSERT ... ON DUPLICATE KEY UPDATE" syntax. You may be able to combine that with LAST_INSERT_ID() (I'm not positive about that)
So:
insert into authid (authid) values ('test') on duplicate key update id=LAST_INSERT_ID(id), authid='test';
select LAST_INSERT_ID();
Well indeed if you try to insert 2 times the same value in a UNIQUE field, it won't work, that's the point of UNIQUE fields.
If I understand well, you want to know if it's possible whether to use an INSERT or an UPDATE statement depending on the existance of an item or not ? Then you need 2 queries, 1 to test existence, the other to insert new value or update existing one
Insert the value conditionally (i.e. if it doesn't exist). Whether the insert takes place or not, by the end of the statement the result will be the same: the value will be in the table. So, just select the ID of the row that matches that value. Or, speaking in SQL, like this:
INSERT INTO authid (authid)
SELECT 'test'
WHERE NOT EXISTS (
SELECT *
FROM authid
WHERE authid = 'test'
);
SELECT id
FROM authid
WHERE authid = 'test'
;
INSERT INTO table('name') VALUES("abc") IF NOT EXISTS name='abc'
If abc doesn't exist in the name column, then insert it. How can I write that query?
INSERT IGNORE INTO table(name) VALUES('abc')
This will ignore the value if it already exists. Like pjotr said, this will require name to be a unique index.
Source
Try:
insert into table('name')
select 'abc'
where not exists (select 1 from table where name='abc')
You may either use REPLACE (syntax, or, equivalent INSERT ON DUPLICATE KEY UPDATE). This is more appropriate if there's more columns and you want to update the others for the given key.
Or the IGNORE modifier (INSERT syntax) along with a unique index for the 'name' column. In that case, the insert will be ignored if it violates the unique index, but won't throw an error. That's more appropriate if you don't want to change any values and just keep the record if it already exists.
One way to do it is testing it with an IF:
IF (select count(*) from table where name = 'abc') = 0
THEN
INSERT INTO table('name') VALUES("abc")
I would enforce the column as UNIQUE and catch the exception on the code side, if you have a unicity constraint on that field. Otherwise I tend to agree with other answers.
I have Some Code...hope it will help you..
mysql_query("INSERT INTO authors (author) VALUES ('$rec_fic_author')
WHERE NOT EXISTS (SELECT * FROM authors WHERE author='$rec_fic_author')")
or die("cannot insert author");
here author is the name of table
authorID (pk)
author $rec_fic_author is _POST variable
In my table I have two fields: v_id and ip_address. I want to insert some data into this table only if the IP address doesn't already exist.
After Google'ing I came across the INSERT IGNORE INTO statement, and this is my code:
public function update_visits($ip_address)
{
$sql = 'INSERT IGNORE INTO `24h_visits` (ip_address) VALUES (?)';
if($this->db->query($sql, array($ip_address)))
{
return TRUE;
}
return FALSE;
}
It runs fine and without errors, but duplicate rows are still being made, even if the same IP is passed in as a parameter.
Anyone got a clue? Thanks.
You have to create a UNIQUE index on ip_address for INSERT IGNORE to work:
ALTER TABLE 24h_visits
ADD UNIQUE INDEX(ip_address)
However, I haven't seen the entirety of your schema, but I would assume that there's a column that stores a timestamp of the last visit. It's the only way this would make sense (so you can purge visits older than 24 hours every now and then).
In this case, you actually don't want INSERT IGNORE, but INSERT ... ON DUPLICATE KEY UPDATE instead. Assuming you have a column called last_visit:
INSERT INTO 24h_visits (ip_address, last_visit)
VALUES ('$ip_address', NOW())
ON DUPLICATE KEY UPDATE last_visit = NOW();
With INSERT IGNORE, the new row is never inserted, and thus you would always have the first value ever inserted on last_visit, which (the way I see it) is not entirely correct.
Add the UNIQUE constraint to your ip_address column.
Then your query would fail if it attempts to add a duplicate ip_address row (unless you use INSERT IGNORE).
The other answers don't actually answer the question: Creating a unique index prevents the duplicate from being inserted, which is a good idea, but it doesn't answer "how to insert if not already there".
This is how you do it:
INSERT IGNORE INTO 24h_visits (ip_address)
select ?
where not exists (select * from 24h_visits where ip_address = ?)
Additionally, this approach does not require any changes to schema.