I would like to insert in my tables ROLES values if it does not exist yet, without using the id
My table ROLES (id, name)
Entries : 'admin', 'superadmin'
Could you please give me an example for MySQL?
I and to Insert the value in name only if this name is not already present in the table
ie. :
INSERT INTO ROLES (name) VALUES ('noadmin') should work
INSERT INTO ROLES (name) VALUES ('admin') should not work
Late info
CREATE TABLE IF NOT EXISTS roles (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4;
The id column is optional if it is an autoincrement / primary key
INSERT IGNORE INTO `roles` VALUES ('admin');
INSERT IGNORE INTO `roles` VALUES ('superadmin');
or
INSERT IGNORE INTO `roles` VALUES ('admin'), ('superadmin');
The INSERT IGNORE statement will cause MySQL to do nothing when the insertion throws an error. If there’s no error, then a new row will be added to the table.
You should have a UNIQUE key constraint set on roles name column to prevent duplicates.
Related
I have a mysql script where I insert values to a type_table. If I execute this script again duplicate values will be inserted in type_table. I don't want to delete the type_table and re-insert because the id is foreign key for many other tables. How do I execute Insert statement only once assuming this script will be executed many times. It's kind of a lookup table that you populate only once in the beginning.
CREATE TABLE IF NOT EXISTS `type_table` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`type_text` VARCHAR(200),
`create_time` DATETIME NOT NULL,
PRIMARY KEY (`id`),
INDEX (`id`)
);
INSERT INTO `type_table` (`create_time`,`type_text`) VALUES
(now(), 'type1' ),
(now(), 'type2' );
you can set 'type_text' as a unique column in database to simply not allowing duplicate values
I have this table
CREATE TABLE IF NOT EXISTS `group` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB;
This is work.
INSERT INTO `group` (`id`) VALUES (NULL);
But I cannot insert record using fat-free
I tried this.
$group=new DB\SQL\Mapper($f3->get('DB'),'group');
$group->save();
and this.
$group=new DB\SQL\Mapper($f3->get('DB'),'group');
$group->id=null;
$group->save();
and this.
$group=new DB\SQL\Mapper($f3->get('DB'),'group');
$group->id='null';
$group->save();
But no one can create record, and also no error.
What is correct way to insert record to this table?
Fat-Free Framework's Mapper doesn't insert records without (changed/new) values besides the primary key. So the $fields array is empty and the Mapper skips the insert operation.
I am not sure if this qualifies as bug.
Here is a simple solution based on your provided query and F3's SQL object:
$sql = $f3->get('DB');
$sql->exec('INSERT INTO group (id) VALUES (NULL)');
EDIT:
I want to update the id to a newly created auto increment id, the rest of the row's columns will not change.
ORIGINAL:
I've got a table in mysql looking like:
id userId productId
all columns are UBIGINT, and id is the PRIMARY KEY, set to AUTO INCREMENT.
So now I want to re-insert a row into the same table, but with a newly created id. And the old row should be deleted!
I'm using the id for order (higher == newer).
Is this possible, because the other option is adding a timestamp column and updating this column, but I won't use the timestamp. So I want to prevent this at all costs.
Let's say we have following table
create table so (
`id` int(11) not null auto_increment,
`num` varchar(20) not null, primary key (`id`),
unique (`num`)
) engine=InnoDB default charset=utf8;
Then we can use following query to insert new row
insert into so (num) values ("hi") on duplicate key update id=last_insert_id()+1;
If there is already "hi"-row this query will update it's id to be equal next after the last inserted
In your case
insert into table (userId, productId) values (someUserId, someProductId)
on duplicate key update id=last_insert_id()+1;
Also, there is replace MySQL extension.
replace into table (userId, productId) values (someUserId, someProductId);
As an on duplicate key update it will only work if your table has unique or primary key constraint.
Unlike on duplicate key update replace will first delete existing row and then insert new, while on duplicate key update will just update it.
INSERT INTO table (userId, productId) VALUES
(SELECT userId, productId FROM table WHERE id=[id of row]);
DELETE FROM table WHERE id=[id of row];
Yes it is possible. You just have to delete the old record and add an other one. But you have to know that the auto_increment will always grow.
A standard problem in applications is to insert a record if one doesn't exist - or update if it does. In cases where the PRIMARY KEY is unknown this is usally solved by issuing a SELECT and then running either an INSERT or UPDATE if the record was found.
However, there seems to be at least three ways I know of that you can insert a record into a database even when a record already exists. Personally, I would rather drop the new insert request if one already exists, but then there might be cases where you would rather drop the record in the database and use the new one.
CREATE TABLE IF NOT EXISTS `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`foo` int(10) unsigned NOT NULL,
`bar` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `row` (`foo`,`bar`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Here are the three methods:
INSERT IGNORE INTO table (foo, bar) VALUES (2,3);
INSERT INTO table (foo, bar) VALUES (2,3) ON DUPLICATE KEY UPDATE;
REPLACE INTO table (foo, bar) VALUES (2,3);
At what times should each of these methods be used?
Can someone give some examples of correct usage scenarios?
INSERT should be used when you just want to insert a new row
Lets say you are storing log entries, you'll want to log every event, use INSERT.
INSERT IGNORE should be used when you just want there to be a specific key exists in the table, it doesn't matter if it's the current insert that creates it, or if it's already present.
Let's say you have a table of phone-numbers and the number of uses, you find a new phone number that you are not sure exists in the table, but you want it to be there.
You use INSERT IGNORE to make sure that it's there.
REPLACE INTO should be used when you want to make sure that a specific key exists in the table, if it exists you'd like the new values to be used, instead of that present.
You have another table with phone-numbers, this time you find a new number and a name to associate it with.
You use REPLACE INTO to find and update a complete record, or just insert the new information.
INSERT INTO ... ON DUPLICATE KEY UPDATE ...
Please not that this is not an alternative method of writing REPLACE INTO, the above should be used whenever you'd like to make sure that a specific key exists, but if it does update some of the columns, not all of them.
For example if you are storing the numbers of visits from a certain IP, and the first page the user ever visited.
INSERT INTO visitors (ip,visits,first_page) VALUES (<ip>,1,<current_page>) ON DUPLICATE KEY visits = visits +1;
In your question, you have
INSERT INTO `table` (foo, bar) VALUES (2,3) ON DUPLICATE KEY UPDATE;
That can only work if the row index was UNIQUE:
CREATE TABLE IF NOT EXISTS `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`foo` int(10) unsigned NOT NULL,
`bar` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `row` (`foo`,`bar`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Otherwise, why have just an index?
Also the ON DUPLICATE KEY clauses allows you to update non-indexed columns.
As for REPLACE, keep in mind that REPLACE is actually DELETE and INSERT under the hood.
I have a table in MySQL with multiple of reported events (primary key, date submitted, and text). Users can "like", or "+1" the reports, similar to facebook/google. Right now, a user can "like" a single event infinite times. What's the best way of arranging the database to check if he's agreed to this even before?
I considered adding a column that can store a huge amount of text and adding a user to this text block if he agrees (comma seperated). I could then explode the text later and search it to see if his name is in there. However, I figured there must be a better way of going about this - any suggestions?
I'd use three tables: event, user and user_likes_event
CREATE TABLE `event` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`submitted` DATE NULL ,
`text` TEXT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
CREATE TABLE `user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
CREATE TABLE `user_likes_event` (
`event_id` INT UNSIGNED NOT NULL ,
`user_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`event_id`, `user_id`) ,
INDEX `fk_user_id` (`user_id` ASC) ,
INDEX `fk_event_id` (`event_id` ASC) ,
CONSTRAINT `fk_event_id`
FOREIGN KEY (`event_id` )
REFERENCES `event` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_user_id`
FOREIGN KEY (`user_id` )
REFERENCES `user` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
Insert some values:
INSERT INTO `event` (submitted, text) VALUES
('2011-06-20', 'Event 1'),
('2011-06-21', 'Event 2'),
('2011-06-22', 'Event 3');
INSERT INTO `user` (name) VALUES
('Tom'), ('Dick'), ('Harry');
INSERT INTO `user_likes_event` (event_id, user_id) VALUES
(1,1), (1,2), (1,3),
(2,1), (2,2), (2,3),
(3,1), (3,2), (3,3);
Every user now likes every event once. If Tom attempts to like Event 1 again, a primary key constraint error is thrown:
INSERT INTO `user_likes_event` (event_id, user_id) VALUES (1,1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'PRIMARY'
If you don't want errors thrown, you could try a conditional insert:
INSERT INTO `user_likes_event` (event_id, user_id)
SELECT 1,1 FROM DUAL
WHERE NOT EXISTS (
SELECT event_id, user_id FROM `user_likes_event`
WHERE event_id = 1 AND user_id = 1
);
See this question for ideas on INSERT WHERE NOT EXISTS alternatives.
See the SELECT Syntax for more information on the DUAL table.
Why wouldn't you have a table like:
UserId INT NOT NULL
Submitted DATE NOT NULL
ReportId INT NOT NULL
PRIMARY KEY (UserId, ReportId)
FOREIGN KEY UserId REFERNCES Users (Id)
FOREIGN KEY ReportId REFERENCES Reports(Id)
That will prohibit "infinite" likes/+1s and you won't have to parse and search large strings. It may not be too efficient once you get lots of millions of "likes" but it should be good for most situations. It depends on how many "likes" you think will be generated and inserted into your database.