MySQL On Duplicate Key Update - mysql

It is only allowing me to update resulting in a total of 2
Heres my Table
CREATE TABLE `cart` (
`id` int(7) NOT NULL AUTO_INCREMENT,
`User` int(7) DEFAULT NULL,
`Product` varchar(100) DEFAULT NULL,
`Quantity` int(7) DEFAULT NULL,
UNIQUE KEY `id` (`id`),
UNIQUE KEY `Quantity` (`Quantity`)
)
Then, my code to insert the data is:
$a = '1'
query2 = " INSERT INTO CART(User, Product,Quantity)
VALUES
('$id','$model_number','$a')
ON DUPLICATE KEY UPDATE Quantity=Quantity+1";
It will work when I Add the data to the database but, upon my second attemp I get this error:
Duplicate entry '2' for key 'Quantity'

You probably don't want this line:
UNIQUE KEY `Quantity` (`Quantity`)
That creates a unique constraint on the quantity field, which is why your second insert is failing. I can't think of any reason why you would want that.
P.S. If you remove that line, make sure to remove the comma (,) from the previous line.

Related

How to avoid duplicate key error in mysql

I have a problem to get a next sequence id in my code. Though it was a legacy code i have to follow the same. Let me explain the logic which was followed.
CREATE TABLE `emp_seq` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1234 DEFAULT CHARSET=utf8
Above table used to get the next sequence id for the below table. and also emp_seq table will have only one entry for the id.
CREATE TABLE `emp_info` (
`id` BIGINT(8) UNSIGNED NOT NULL,
`name` VARCHAR(128) DEFAULT '',
`active` TINYINT(2) DEFAULT '1',
`level` MEDIUMINT(8) DEFAULT '100',
PRIMARY KEY (`id`),
KEY `level` (`level`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='employee information'
so whenever we trying to insert a new record to emp_info table, we are getting next sequence id from the table emp_seq by using below queries.
INSERT INTO emp_seq () VALUES ();
DELETE FROM emp_seq WHERE id < LAST_INSERT_ID;
Now the problem is, some times because of multiple asynchronous calls in the application, the same increment id has been shared to multiple records and trying to insert in the emp_info table and we are getting below error
"code":"ER_DUP_ENTRY","errno":1062,"sqlMessage":"Duplicate entry 1234 for key
Kindly help me how to resolve the issue.

Is it possible to make a batch insert/update if the uniqueness of the record is a bundle of two fields?

I have the following table structure (example)
CREATE TABLE `Test` (
`id` int(11) NOT NULL,
`order_id` int(11) NOT NULL,
`position_id` int(11) NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`price` decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `Test` ADD PRIMARY KEY (`id`);
ALTER TABLE `Test` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
This table contains data that is constantly in need of updating. There is also new data that needs to be entered. Since there is a lot of data, it will take quite a long time to check each record to make it insert or update.
After studying the question, I realized that I need to use batch insert/update with:
INSERT on DUPLICATE KEY UPDATE
But the documentation says that the fields must have a unique index. But I don't have any unique fields, I can't use the ID field. The uniqueness of the record can only be in a combination of two fields order_id and position_id.
Is it possible to make a batch insert/update if the uniqueness of the record is a bundle of two fields?
You need a composite primary-key. You also don't need your AUTO_INCREMENT id column, so you can drop it.
Like so:
CREATE TABLE `Test` (
`order_id` int NOT NULL,
`position_id` int NOT NULL,
`name` varchar(255) NOT NULL COLLATE utf8mb4_unicode_ci,
`price` decimal(10,2) NOT NULL,
CONSTRAINT PK_Test PRIMARY KEY ( `order_id`, `position_id` )
) ENGINE=InnoDB
Then you can use INSERT ON DUPLICATE KEY UPDATE.

Foreign key constraint fails but referenced row exists

I'm running MySQL 5.7.21 on Amazon RDS.
I know this question has been asked a thousand times, but I'm getting the issue on a scenario I wouldn't expect, so please read through before downvoting or marking as duplicate.
I'm not restoring the database, just running single INSERT queries, so is not a matter of ordering.
The referenced row does exist on the table; me and my colleagues had it triple checked.
As one might expect, disabling the FK checks with SET foreign_key_checks = 0 does make the query work.
I've seen this happening because of different table charsets, but in this case, both use utf8mb4. Also both have collation set to utf8mb4_general_ci.
This is happening in a production environment, so dropping the tables and recreating them is something I would like to avoid.
Some additional information:
The FK constraint was created AFTER the original tables were already populated.
Here is the relevant portion of the current DDL:
CREATE TABLE `VehicleTickets` (
`id` varchar(50) NOT NULL,
`vehiclePlate` char(7) NOT NULL,
`organizationId` varchar(50) NOT NULL,
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` timestamp NULL DEFAULT NULL,
`status` varchar(15) NOT NULL DEFAULT 'OPEN',
`description` text NULL DEFAULT NULL,
`ticketInfo` json DEFAULT NULL,
`externalId` varchar(100) GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.externalId'))) VIRTUAL,
`value` decimal(10,2) GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.value'))) VIRTUAL,
`issuedAt` timestamp GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.issuedAt'))) VIRTUAL NOT NULL,
`expiresAt` timestamp GENERATED ALWAYS AS (json_unquote(json_extract(`ticketInfo`,'$.expiresAt'))) VIRTUAL NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `VehicleTickets_externalId_unq_idx` (`externalId`,`organizationId`),
KEY `VehicleTickets_vehiclePlate_idx` (`vehiclePlate`),
KEY `VehicleTickets_organizationId_idx` (`organizationId`),
KEY `VehicleTickets_issuedAt_idx` (`createdAt`),
KEY `VehicleTickets_expiresAt_idx` (`expiresAt`),
CONSTRAINT `VehicleTickets_Organizations_fk`
FOREIGN KEY (`organizationId`) REFERENCES `Organizations` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `Organizations` (
`id` varchar(50) NOT NULL,
`name` varchar(100) NOT NULL,
`taxPayerId` varchar(50) DEFAULT NULL,
`businessName` varchar(100) DEFAULT NULL,
`status` varchar(15) NOT NULL DEFAULT 'TESTING',
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`activatedAt` timestamp NULL DEFAULT NULL,
`assetConfiguration` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
When I run:
select * from VehicleTickets where organizationId not in (
select id from Organizations
);
I get an empty result set.
However, if I run a query like this:
insert into `VehicleTickets` (
`id`,
`createdAt`,
`organizationId`,
`ticketInfo`,
`vehiclePlate`
)
values (
'... application generated id',
'... current date ',
'cjlchoksi01r8nfks3f51kht8', -- DOES EXIST on Organizations
'{ ... some JSON payload }',
'... vehicle plate'
)
This produces the following error:
Cannot add or update a child row: a foreign key constraint fails
(VehicleTickets, CONSTRAINT VehicleTickets_Organizations_fk
FOREIGN KEY (organizationId) REFERENCES Organizations (id))
Additionally, it gives me:
"errno": 1452,
"sqlState": "23000",
I've read through several threads regarding this issue, but couldn't find a similar case.

Issue in insert query mysql error#1364

my query is
INSERT INTO `session_card` (`flags`, `history`, `showtime`, `session_id`, `card_id`, `card_mode`) VALUES ('', 'ö', '12', 9410, '256', 'rw')
and the table structure is
DROP TABLE IF EXISTS `session_card`;
CREATE TABLE IF NOT EXISTS `session_card` (
`id` int(11) NOT NULL,
`session_id` int(11) DEFAULT NULL,
`card_id` int(100) DEFAULT NULL,
`history` varchar(1000) DEFAULT NULL,
`flags` varchar(255) NOT NULL DEFAULT '',
`showtime` varchar(2000) DEFAULT NULL,
`card_mode` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `session_card_unique_key` (`session_id`,`card_id`,`card_mode`),
KEY `fk` (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
COMMIT;
Now I dont understand what is the issue here also my phpmyadmin show only error code it doesnt give me the error expatiation. Any one can help me with this.
You need to have AUTO_INCREMENT on your id column, or you will need to pass a unique id manually every time you insert a row.
Change:
CREATE TABLE IF NOT EXISTS `session_card` (
`id` int(11) NOT NULL,
to:
CREATE TABLE IF NOT EXISTS `session_card` (
`id` int(11) NOT NULL AUTO_INCREMENT,
I would also suggest adding UNSIGNED as well since id's usually don't contain negative values.
In your schema, you have given id` int(11) NOT NULL but while inserting data you are not passing any value for id. as id is a not null constraint you should pass the value for id.
Modify you ID column to AUTO_INCREMENT flag
ALTER TABLE session_card MODIFY id int NOT NULL AUTO_INCREMENT
Make sure you table is empty before executing the above sql
If you are not setting a primary key id to Auto Increment then provide a value while inserting.
Otherwise, set it to AutoIncrement. This is better way to assigning a value.
INSERT INTO `session_card`
(`id`,`flags`, `history`, `showtime`, `session_id`, `card_id`, `card_mode`) VALUES
('1','', 'ö', '12', 9410, '256', 'rw')
Might be it's because of strick mode
Disable it:
SET sql_mode = '';
After this try insert query.
please make id key is auto increment
like following.
ALTER TABLE session_card MODIFY id int NOT NULL AUTO_INCREMENT
Otherwise add manually id at insertion time. like following.
INSERT INTO session_card
(id,flags, history, showtime, session_id, card_id, card_mode) VALUES
('1','', 'ö', '12', 9410, '256', 'rw')

Nested sql insert from php

I have a nested array in php and I'm trying to insert data into a mysql table only if a duplicate does not exist. The duplicate should only check match against the sensor_serial and dates field. I'm having no luck with DUPLICATE as the id is unique regardless of the other fields. this is the table layout:
CREATE TABLE IF NOT EXISTS `temps_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sensor_serial` varchar(64) COLLATE latin1_general_ci DEFAULT NULL,
`temp_c` float DEFAULT NULL,
`dates` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `date` (`dates`)
)
This is my non working code. I can't seem to get it quite right.
foreach ($output as $k => &$v) {
$sql = "INSERT INTO temps_test (sensor_serial,temp_c,dates) VALUES ('$v[7]','$v[3]','$v[5]') WHERE NOT EXISTS (SELECT * FROM temps_test WHERE sensor_serial='$v[7]' AND dates='$v[5]')";
$go = mysql_query($sql) or die( mysql_error() );
}
Can this be done this way or is my approach totally off?
Try using ON DUPLICATE KEY UPDATE
INSERT INTO temps_test (sensor_serial,temp_c,dates)
VALUES ('val1','val2','val3')
ON DUPLICATE KEY UPDATE sensor_serial=sensor_serial;
make sure to add constraint on field sensor_serial, example
CREATE TABLE IF NOT EXISTS `temps_test`
(
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sensor_serial` varchar(64) COLLATE latin1_general_ci DEFAULT NULL,
`temp_c` float DEFAULT NULL,
`dates` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `date` (`dates`),
CONSTRAINT t_uq INIQUE (`sensor_serial`) -- <== this one
)