I'm trying to insert new rows into a MySQL table, but only if one of the values that I'm inserting isn't in a row that's already in the table.
For example, if I'm doing:
insert into `mytable` (`id`, `name`) values (10, `Fred`)
I want to be able to check to see if any other row in the table already has name = 'Fred'. How can this be done?
Thanks!
EDIT
What I tried (can't post the exact statement, but here's a representation):
INSERT IGNORE INTO mytable (`domain`, `id`)
VALUES ('i.imgur.com', '12gfa')
WHERE '12gfa' not in (
select id from mytable
)
which throws the 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 'WHERE '12gfa' not in ( select id from mytable)' at line 3
First of all, your id field should be an autoincrement, unless it's a foreign key (but I can't assume it from the code you inserted in your question).
In this way you can be sure to have a unique value for id for each row.
If it's not the case, you should create a primary key for the table that includes ALL the fields you don't want to duplicate and use the INSERT IGNORE command.
Here's a good read about what you're trying to achieve.
You could use something like this
INSERT INTO someTable (someField, someOtherField)
VALUES ("someData", "someOtherData")
ON DUPLICATE KEY UPDATE someOtherField=VALUES("betterData");
This will insert a new row, unless a row already exists with a duplicate key, it will update it.
DELIMITER |
CREATE PROCEDURE tbl_update (IN id INT, IN nm VARCHAR(15))
BEGIN
DECLARE exst INT;
SELECT count(name) INTO exst FROM mytable WHERE name = nm;
IF exst = 0 THEN
INSERT INTO mytable VALUES(id, name);
END IF;
END
|
DELIMITER ;
or just make an attribute name as UNIQUE
Related
So I read the other posts but this question is unique. So this SQL dump file has this as the last entry.
INSERT INTO `wp_posts` VALUES(2781, 3, '2013-01-04 17:24:19', '2013-01-05 00:24:19'.
I'm trying to insert this value to the table...
INSERT INTO `wp_posts` VALUES(5, 5, '2005-04-11 09:54:35', '2005-04-11 17:54:35'
it gives me the error, "Column count doesn't match value count at row 1." So I'm lost on the concept of how the column and row apply here.
Doesn't 2781,3 mean row 2781 and column 3? And doesn't 5,5 mean row 5 and column 5?
The error means that you are providing not as much data as the table wp_posts does contain columns. And now the DB engine does not know in which columns to put your data.
To overcome this you must provide the names of the columns you want to fill. Example:
insert into wp_posts (column_name1, column_name2)
values (1, 3)
Look up the table definition and see which columns you want to fill.
And insert means you are inserting a new record. You are not modifying an existing one. Use update for that.
you missed the comma between two values or column name
you put extra values or an extra column name
You should also look at new triggers.
MySQL doesn't show the table name in the error, so you're really left in a lurch. Here's a working example:
use test;
create table blah (id int primary key AUTO_INCREMENT, data varchar(100));
create table audit_blah (audit_id int primary key AUTO_INCREMENT, action enum('INSERT','UPDATE','DELETE'), id int, data varchar(100) null);
insert into audit_blah(action, id, data) values ('INSERT', 1, 'a');
select * from blah;
select * from audit_blah;
truncate table audit_blah;
delimiter //
/* I've commented out "id" below, so the insert fails with an ambiguous error: */
create trigger ai_blah after insert on blah for each row
begin
insert into audit_blah (action, /*id,*/ data) values ('INSERT', /*NEW.id,*/ NEW.data);
end;//
/* This insert is valid, but you'll get an exception from the trigger: */
insert into blah (data) values ('data1');
MySQL will also report "Column count doesn't match value count at row 1" if you try to insert multiple rows without delimiting the row sets in the VALUES section with parentheses, like so:
INSERT INTO `receiving_table`
(id,
first_name,
last_name)
VALUES
(1002,'Charles','Babbage'),
(1003,'George', 'Boole'),
(1001,'Donald','Chamberlin'),
(1004,'Alan','Turing'),
(1005,'My','Widenius');
You can resolve the error by providing the column names you are affecting.
> INSERT INTO table_name (column1,column2,column3)
`VALUES(50,'Jon Snow','Eye');`
please note that the semi colon should be added only after the statement providing values
In my case i just passed the wrong name table, so mysql couldn't find the right columns names.
So I read the other posts but this question is unique. So this SQL dump file has this as the last entry.
INSERT INTO `wp_posts` VALUES(2781, 3, '2013-01-04 17:24:19', '2013-01-05 00:24:19'.
I'm trying to insert this value to the table...
INSERT INTO `wp_posts` VALUES(5, 5, '2005-04-11 09:54:35', '2005-04-11 17:54:35'
it gives me the error, "Column count doesn't match value count at row 1." So I'm lost on the concept of how the column and row apply here.
Doesn't 2781,3 mean row 2781 and column 3? And doesn't 5,5 mean row 5 and column 5?
The error means that you are providing not as much data as the table wp_posts does contain columns. And now the DB engine does not know in which columns to put your data.
To overcome this you must provide the names of the columns you want to fill. Example:
insert into wp_posts (column_name1, column_name2)
values (1, 3)
Look up the table definition and see which columns you want to fill.
And insert means you are inserting a new record. You are not modifying an existing one. Use update for that.
you missed the comma between two values or column name
you put extra values or an extra column name
You should also look at new triggers.
MySQL doesn't show the table name in the error, so you're really left in a lurch. Here's a working example:
use test;
create table blah (id int primary key AUTO_INCREMENT, data varchar(100));
create table audit_blah (audit_id int primary key AUTO_INCREMENT, action enum('INSERT','UPDATE','DELETE'), id int, data varchar(100) null);
insert into audit_blah(action, id, data) values ('INSERT', 1, 'a');
select * from blah;
select * from audit_blah;
truncate table audit_blah;
delimiter //
/* I've commented out "id" below, so the insert fails with an ambiguous error: */
create trigger ai_blah after insert on blah for each row
begin
insert into audit_blah (action, /*id,*/ data) values ('INSERT', /*NEW.id,*/ NEW.data);
end;//
/* This insert is valid, but you'll get an exception from the trigger: */
insert into blah (data) values ('data1');
MySQL will also report "Column count doesn't match value count at row 1" if you try to insert multiple rows without delimiting the row sets in the VALUES section with parentheses, like so:
INSERT INTO `receiving_table`
(id,
first_name,
last_name)
VALUES
(1002,'Charles','Babbage'),
(1003,'George', 'Boole'),
(1001,'Donald','Chamberlin'),
(1004,'Alan','Turing'),
(1005,'My','Widenius');
You can resolve the error by providing the column names you are affecting.
> INSERT INTO table_name (column1,column2,column3)
`VALUES(50,'Jon Snow','Eye');`
please note that the semi colon should be added only after the statement providing values
In my case i just passed the wrong name table, so mysql couldn't find the right columns names.
I create a script/workflow exportation/importation from 2 system.
I have Table1 {id, name, description}
I want to create a script (not a procedure). I could (I didnt succed) adding procedure into my workflow. (create and delete at the end)
id is auto increment
I cant change the table
I can be sure that between the time I start execution of my script and the end, there will not be an insertion of one of my items into the database.
The script insert {name,description} but I want to NOT insert if the element (name or name and description) is there.
BASE QUERY :
INSERT INTO TABLE1 (name,description) VALUES ('itemX','this is item X')
BASE Script :
Use database1;
BEGIN;
SELECT * FROM TABLE1 ;
SELECT * FROM TABLE3 ;
INSERT INTO TABLE1 (name,description) VALUES ('itemX','this is item X');
set #idTable1 = LAST_INSERT_ID();
INSERT INTO TABLE3 (idTable1,idTable2) VALUES (#idTable1,1);
INSERT INTO TABLE3 (idTable1,idTable2) VALUES (#idTable1,2);
SELECT * FROM TABLE1 ;
SELECT * FROM TABLE3 ;
ROLLBACK;
I want to protect the multiple insertion on TABLE1. But without changing the table.
Maybe I did it wrong
I tried IF but not working outside procedure.
I tried IGNORE (valid only if id is the same, but never the same, its
auto increment)
I tried WHEN
I tried ON DUPLICATE KEY
Because of #idTable1, I will need change the " set #idTable1 = LAST_INSERT_ID();" if I doesnt have if else. But if my item is the only one with the same "name", I can get this instead of last_insert_id.
I opted for creating procedure before my "BEGIN" and removed them at the end of the script.
Just create the table with name as primary key, then be sure that you take care of the key capitalization (uppercase or lowercase) to avoid duplicates.
CREATE TABLE TABLE1(
id INT AUTO_INCREMENT,
name CHAR(30),
description CHAR(100),
PRIMARY KEY (name)
)
create unique constraint on name field if possible.
Otherwise, create trigger before insert in order to ignore duplicate insertion.
Trigger for checking duplicate on two fields a and b:
delimiter //
drop trigger if exists aborting_trigger //
create trigger aborting_trigger before insert on t
for each row
begin
set #found := false;
select true into #found from t where a=new.a and b=new.b;
if #found then
signal sqlstate '45000' set message_text = 'duplicate insert';
end if;
end //
delimiter ;
The trigger here provides feature similar to unique constraint. After creation you should use INSERT IGNORE or INSERT ...ON DUPLICATE KEY UPDATE
I'm trying to add a value to a table but not without checking if the value already exists. This is what I have so far:
IF NOT EXISTS (
SELECT series.seriesName
FROM series
WHERE series.seriesName='Avengers'
)
BEGIN
INSERT INTO series (seriesName) VALUES 'Avengers'
END;
Database is a MySQL db on Ubuntu
You can use IGNORE keyword here.
It could look like:
INSERT IGNORE INTO series (seriesName) VALUES 'Avengers'
The important thing is to create a unique key on seriesName field as it seems that you want it to be unique.
INSERT IGNORE doesn't make the insert when key value already exists.
If you would like to be able to get id (primary key value) for row that wasn't inserted (already existed), you can do the following trick:
INSERT IGNORE INTO series (seriesName) VALUES 'Avengers'
ON DUPLICATE KEY UPDATE seriesID= LAST_INSERT_ID(seriesID)
Then you will be able to get the ID with LAST_INSERT_ID() function no matter if the row was inserted or not.
Query:
INSERT INTO `metadata` (`group_id`, `key`, `value`)
VALUES ("19", "originality", "2")
ON DUPLICATE KEY UPDATE (`group_id` = `19`, `key`=`originality`, `value`=`2`)
The table:
group_id | key | value
----------------------------------------
group_id and key both have a UNIQUE index.
The error happens when I try to run the query when a row already exists with the id 19. The way I want the query to function is, if there is no row with that id, insert it and if there is update it instead of inserting a new row.
The error message I get is the typical:
I'm not sure if a ( should follow the UPDATE keyword - I think not. So try
ON DUPLICATE KEY UPDATE `group_id` = 19, `key`='originality', `value`=2
(or replace group_id with submission_group_id - your error message doesn't seem to match the original query)
you can only use ` on table columns and table names, not for data.
data should use ' or "
like:
ON DUPLICATE KEY UPDATE `group_id` = 19, `key`="originality", `value`=2
The quote tag must be the ' character not the ` character.
if there is no row with that id, insert it and if there is update it instead of inserting a new row.
If you want to do this you should try statement like:
IF EXISTS (SELECT * FROM sometable WHERE ColumnName='somevalue')
UPDATE sometable SET (...) WHERE ColumnName='somevalue'
ELSE
INSERT INTO Table1 VALUES (...)