I have a datetime (name:lud) variable in my database table. It registers in this format 2011-04-11 07:08:02. Now i want to make an unique key in combination with an article_id: article_id + lud.
But for the unique key lud part only 2011-04-11 07:08 is needed.
eg lud 2011-04-11 07:08 + article_id 45
As a variant - you could change type of the lud field to VARCHAR and use length option of index.
For example:
CREATE TABLE mytable(
article_id INT(11) DEFAULT NULL,
lud VARCHAR(19) DEFAULT NULL,
UNIQUE INDEX UK_mytable (article_id, lud (16))
)
ENGINE = INNODB;
INSERT INTO mytable VALUES
(1, '2011-04-11 07:08:11');
Query OK, 1 row affected (0.01 sec)
INSERT INTO mytable VALUES
(1, '2011-04-11 07:09:11');
Query OK, 1 row affected (0.01 sec)
INSERT INTO mytable VALUES
(1, '2011-04-11 07:09:30');
ERROR 1062 (23000): Duplicate entry '1-2011-04-11 07:09' for key 'UK_mytable'
Try this
CONCAT(DATE_FORMAT(lud,'%Y-%m-%d %H:%i'),article_id)
Related
I have a table with auto-incremented ID, colA and colB (with set default value), e.g.:
CREATE TABLE `some_db`.`test` ( `id` INT NOT NULL AUTO_INCREMENT , `colA` INT NOT NULL , `colB` INT NOT NULL DEFAULT '0' , PRIMARY KEY (`id`)) ENGINE = InnoDB;
Now, I want user to be able to insert the new row, but at the same time DO NOT allow to modify id (auto-incremented) or colB (just use default value).
Is that possible?
I tried to give INSERT and UPDATE only for colA, but that still gives me INSERT command denied error:
GRANT SELECT, INSERT (`colA`), UPDATE (`colA`) ON `some_db`.`test` TO 'test_user'#'%';
I don't know if that matters, I'm using MariaDB.
Thanks!
EDIT:
OK, I need to re-state my question now.
After executing e.g.:
INSERT INTO `test` (`colA`) VALUES (10)
Everything is working fine.
But phpmyadmin GUI (that I use as a front-end here) is translating to:
INSERT INTO `test` (`id`, `colA`, `colB`) VALUES (NULL, 10, ``)
...when no values are given, and it can't be executed (#1143 - INSERT command denied to user test_user#...
So, is there any way that rows can be inserted through phpmyadmin GUI (not SQL command) with such restrictions? (I edited the question title).
CREATE TABLE `test` ( `id` INT NOT NULL AUTO_INCREMENT ,
`colA` INT NOT NULL ,
`colB` INT NOT NULL DEFAULT '0' ,
PRIMARY KEY (`id`)) ENGINE = InnoDB;
CREATE TRIGGER tr_bi_test
BEFORE INSERT
ON test
FOR EACH ROW
SET NEW.id = NULL, NEW.colB = 0;
INSERT INTO test (colA) VALUES (11);
INSERT INTO test (colA, colB) VALUES (22, 222);
INSERT INTO test (id, colA) VALUES (3333, 33);
INSERT INTO test (id, colA, colB) VALUES (4444,44,444);
SELECT * FROM test;
id
colA
colB
1
11
0
2
22
0
3
33
0
4
44
0
db<>fiddle here
You cannot use DEFAULT keyword for assigning the value to NEW.colB - in MariaDB it is treated as NULL while using in a trigger. So you need to hardcode this default value, or you may query it from INFORMATION_SCHEMA.COLUMNS.
If I execute the following statement:
INSERT INTO users(id, username) VALUES(102, 'test') ON DUPLICATE KEY UPDATE username='test';
And if the value for column id exists in DB, but the value for username is different, then the reported number of affected rows is 2. To be more precise:
If the new record is an exact duplicate, and nothing is updated/inserted then the affected rows is 0
If the id does not exist yet, then a new record is inserted, and affected rows is 1
If the id exists, but the existing record is updated the value for affected rows is set to 2
What is the reason for this? Is this to provide information back of what action took place? Are there actually 2 rows being affected?
Tested on MariaDB 10.3.7 with
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(355) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8mb4;
INSERT INTO `users` (`id`, `username`) VALUES (102, 'Some name');
INSERT... ON DUPLICATE KEY UPDATE executes two actions. You can demonstrate this with triggers that set session variables as a side-effect:
mysql> create trigger i before insert on users for each row set #i = true;
mysql> create trigger u before update on users for each row set #u = true;
mysql> INSERT INTO users(id, username) VALUES(102, 'test') ON DUPLICATE KEY UPDATE username='test';
Query OK, 2 rows affected (0.01 sec)
mysql> select #i, #u;
+------+------+
| #i | #u |
+------+------+
| 1 | 1 |
+------+------+
In MySQL database I have the data
create table student(user_id int(20) unsigned NOT NULL AUTO_INCREMENT,
name varchar(20),
email varchar(20),
primary key(user_id,email));
I want to use user_id and email field should be unique value.
I also add
alter table student add unique unique_index (user_id,email);
but still it accepts all the entry
mysql> insert into student (name, email) values ("a", "aa", "aa");
Query OK, 1 row affected (0.06 sec)
mysql> insert into student (name, email) values ("a", "aa", "aa");
Query OK, 1 row affected (0.06 sec)
select * from student;
+---------+------+-------+
| user_id | name | email |
+---------+------+-------+
| 1 | a | aa |
| 2 | a | aa |
+---------+------+-------+
2 rows in set (0.00 sec)
how can I make that fields(id and email) as unique?
you can use like these. Here every unique index name should be different.
CREATE TABLE student(user_id INT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
NAME VARCHAR(20),
email VARCHAR(20),
PRIMARY KEY(user_id,email));
unique index creation.
ALTER TABLE student ADD UNIQUE unique_index1 (user_id);
ALTER TABLE student ADD UNIQUE unique_index2 (email);
Inserting data:
INSERT INTO student (`name`, email) VALUES ("a", "aa");
Execute below SQL it gives error.
INSERT INTO student (`name`, email) VALUES ("a", "aa");
Thank you.
As my understandind of your requirement is correct, you have to add to unique indexes:
alter table student add unique unique_index (user_id);
alter table student add unique unique_index_email (email);
Your statement will create a index where the combination of user_id and email is unique!
Structure table:
CREATE TABLE IF NOT EXISTS `table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rows_id` int(11) NOT NULL,
`url_id` int(11) NOT NULL,
`keyword_id` int(11) NOT NULL,
`date` datetime NOT NULL,
`seet` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
STRUCTURE TABLE WITH TEST ROWS ON SQLFIDDLE
query insert:
INSERT INTO `table` (`id`, `rows_id`, `url_id`, `keyword_id`, `date`, `seet`)
VALUES
(1, 1, 2, 1, '2014-05-01 00:00:00', 1);
I would like insert this row or update row if table already have row with date = '2014-05-01 00:00:00' and rows_id = '1' and keyword_id = '1'.
In dev.mysql.com i see query INSERT ... ON DUPLICATE KEY UPDATE but how make insert or update in my case ?
INSERT...ON DUPLICATE KEY UPDATE (IODKU) does an update only if the values you insert conflict with an existing row based on a PRIMARY KEY or UNIQUE KEY.
So you need to define a UNIQUE KEY over the three columns or else IODKU can't tell if the row conflicts with an existing one.
ALTER TABLE `table` ADD UNIQUE KEY (date, rows_id, keyword_id);
You said in a comment above that you can have more than one row with the same rows_id. That's fine -- the unique constraint says that you can't have two rows that duplicate the same combination of three values in date, rows_id, and keyword_id. But you can have multiple rows that have the same value in any one of those columns, as long as the combination of the three is unique.
Here's a quick demo:
mysql> create table t (
id int auto_increment primary key,
d int,
r int,
k int,
unique key(d,r,k)
);
mysql> insert into t values (1,1,1,1);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t values (1,1,1,1) on duplicate key update d = values(d)+1;
Query OK, 2 rows affected (0.00 sec)
mysql> select * from t;
+----+------+------+------+
| id | d | r | k |
+----+------+------+------+
| 1 | 2 | 1 | 1 |
+----+------+------+------+
From what I'm understanding from your question, this might help. This SQL Query will test if a row exists and update the row or create a new one based on whether or not that row already exists.
IF EXISTS (SELECT * FROM table WHERE date = 2014-05-01 00:00:00 AND rows_id = 1 AND keyword_id = 1)
BEGIN
UPDATE table SET Params=values
END
ELSE
BEGIN
INSERT INTO `table` (`id`, `rows_id`, `url_id`, `keyword_id`, `date`, `seet`) VALUES (1, 1, 2, 1, '2014-05-01 00:00:00', 1)
END
If the row exists (if the SELECT statement returns data) the UPDATE query will run. If the row does not exist (SELECT statement returns no data) then the INSERT INTO statement will run.
CREATE TABLE IF NOT EXISTS `foo` (
`foo_id` INT NOT NULL AUTO_INCREMENT ,
`unique` CHAR(255) NULL ,
`not_unique` CHAR(255) NULL ,
PRIMARY KEY (`foo_id`) ,
UNIQUE INDEX `unique_UNIQUE` (`unique` ASC) )
ENGINE = InnoDB;
This is the table.
INSERT INTO foo (`unique`,`not_unique`) VALUES ('John','Doe')
ON DUPLICATE KEY UPDATE `foo_id`=LAST_INSERT_ID(`foo_id`);
SELECT LAST_INSERT_ID();
LAST_INSERT_ID here returns 1. That is correct.
INSERT INTO foo (`unique`,`not_unique`) VALUES ('John','Doe')
ON DUPLICATE KEY UPDATE `foo_id`=LAST_INSERT_ID(`foo_id`);
SELECT LAST_INSERT_ID();
LAST_INSERT_ID here returns 1. That is correct.
INSERT INTO foo (`unique`,`not_unique`) VALUES ('Jane','Doe')
ON DUPLICATE KEY UPDATE `foo_id`=LAST_INSERT_ID(`foo_id`);
SELECT LAST_INSERT_ID();
LAST_INSERT_ID here returns 3. Why? I was hoping it to be 2. If this is a bug, is there a workaround for it?
The id was taken at the beginning of the attempted insert, and was discarded on failure.