I have a query which updates the table or inserts if the row does not already exist, but for some reason it just inserts all the time.
This is my table structure:
Id (primary) | uid | product_id | quantity
This is my query:
INSERT INTO my_table (uid,product_id,quantity)
SELECT t1.uid,?,?
FROM checker t1
WHERE t1.id = ?
ON DUPLICATE KEY UPDATE
product_id = ?, quantity = quantity+?
What i want to do though is use on duplicate key if uid + product_id combination exist in the table already.
So is there a way to designate what kind of duplication to look for to update instead of insert?
There is no way to distinguish between what duplication occurs.
As soon as any unique constraint is violated - it will perform ON DUPLICATE KEY UPDATE part.
For your case you just need to create unique composite key that consists of 2 fields: (uid, product_id)
Related
I have the following table:
questions_answers
_____________________________________
| id | question_id | answer | user_id |
|____|_____________|________|_________|
| 1 | 1 | yes | 3 |
|____|_____________|________|_________|
I want to check if question_id and user_id exist, Then update the existing row.
I tried this command INSERT INTO questions_answers (question_id, answer, user_id) VALUES (1, 'no',3) ON DUPLICATE KEY UPDATE answer = 'no'
So in this case there is a question_id = 1 and user_id = 3, Hence it should update that row and not insert a new row.
But I think it checks the id column for dublicates.
Is there is a way to get this done with SQL or I need to check if row exists with PHP, then update?
Your INSERT INTO .. ON DUPLICATE KEY UPDATE is not working because the current KEY that determine the duplication/violation is the id column primary key.
From the spec of this syntax
INSERT ... ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT statement that, if it finds a duplicate unique or primary key, will instead perform an UPDATE.
To achieve this, you will need to create a UNIQUE CONSTRAINT on two columns question_id and user_id. This unique constraint will raise upon the duplication of question_id - user_id pair, and triggers the UPDATE statement as you intends.
ALTER TABLE questions_answers ADD CONSTRAINT uq_user_question UNIQUE KEY(question_id ,user_id);
Reference:
MySQL Insert On Duplicate
MariaDB - INSERT ON DUPLICATE KEY UPDATE
I have a table user. It has columns id and email.
USER TABLE
id | email
1 | xxx#gmail.com
2 | yyy#gmail.com
The id is a PRIMARY KEY AUTO_INCREMENT and the email is an UNIQUE KEY.
When I insert a new row in the table and there is a DUPLICATE KEY exception thrown. I want to fetch the id on which the DUPLICATE KEY exception was thrown.
Right now I am doing this -
BEGIN
DECLARE EXIT HANDLER FOR 1062
BEGIN
SELECT id
INTO id
FROM user
WHERE email = 'xxx#gmail.com';
END;
INSERT INTO user
(email)
VALUES
('xxx#gmail.com');
SELECT LAST_INSERT_ID() INTO id;
END;
I want to know if there is a better way to do this. That is to avoid scanning the table again to get the id for which it had already scanned to check the uniqueness of the email.
In scaning by UNIQUE KEY BTREE is used so it's quite fast.
Don't you want check for existing of value by yourself in additional select query
Use INSERT ... ON DUPLICATE KEY UPDATE, then get the autoincremented id as usual:
If a table contains an AUTO_INCREMENT column and INSERT ... ON DUPLICATE KEY UPDATE inserts or updates a row, the LAST_INSERT_ID() function returns the AUTO_INCREMENT value. Exception: For updates, LAST_INSERT_ID() is not meaningful prior to MySQL 5.1.12. However, you can work around this by using LAST_INSERT_ID(expr). Suppose that id is the AUTO_INCREMENT column. To make LAST_INSERT_ID() meaningful for updates, insert rows as follows:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
already searched for such topics and found 2 different solutions but noone works.
My table has structure | ID (auto_increment primary_key) | UID (int) | FAV_ID (int) |
I need to insert new record to this FAV_TABLE if UID and FAV_ID (both) already exist.
Example of my query:
INSERT INTO FAV_TABLE (uid, fav_id) VALUES ($u_id,$s_id) ON DUPLICATE KEY UPDATE uid = uid
or this one
INSERT IGNORE FAV_TABLE (uid, fav_id) VALUES ($u_id,$s_id);
As mysql manuals says this query doesn't add record only if PRIMARY_KEY is the same.
And I need query not to add record if pair uid+fav_id is unique.
Any solutions? Thank you
You need to add a UNIQUE KEY on those columns:
ALTER TABLE FAV_TABLE ADD UNIQUE KEY(uid, fav_id);
INSERT IGNORE or ON DUPLICATE KEY works only when a unique key is duplicated.
You need to add a UNIQUE index on both fields uid and fav_id.
That way, when you insert a duplicate pair, it will be ignored.
I have a table containing all sort of parameters.
The structure of the table is : id, object_id, param_name, param_value
The following code works, but it appends results instead of updating them.
The fact is that I can't use ON DUPLICATE KEY because my fields are non-uniques (except for id of course)
INSERT INTO `params_table` (`object_id`, `param_name`, `param_value`)
SELECT
A.id AS my_object_id,
'XYZ' AS my_param_name,
IF(TMP.abc IS NULL,0,1) AS my_param_value
FROM
ref_table AS A
LEFT JOIN tmp_table AS TMP ON TMP.abc = A.abc
ON DUPLICATE KEY
UPDATE `param_value` = IF(TMP.abc IS NULL,0,1);
The ON DUPLICATE KEY clause does not only work on the primary key:
If you specify ON DUPLICATE KEY
UPDATE, and a row is inserted that
would cause a duplicate value in a
UNIQUE index or PRIMARY KEY, an UPDATE
of the old row is performed
So unless I'm missing something obvious you simply need to create a unique index on the column combination you want to make unique:
ALTER TABLE params_table
ADD UNIQUE unique_object_param(object_id,param_name);
I have 2 tables: let say table 1 (userid, username, password) and table 2 (userid, a, b, c).
table 1 has a userid field (primary key), table 2 also has userid (references table 1).
If I do an insert statement, to add a row to table 2, how does table 2 generate the userid field?
Edit:
I want to insert things into table 2 where the userid in table 2 MUST match userid in table 1 - what constraints do I need to set up
The database doesn't understand the relationship between table1 and table2 unless you explicitly specify it. You can use SQL foreign keys if you are using a database engine the supports them (InnoDB).
CREATE TABLE table1 (
userid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL);
CREATE TABLE table2 (
rowid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
userid INTEGER NOT NULL
REFERENCES table1(userid)
ON DELETE CASCADE ON UPDATE CASCADE
-- other columns here
);
The REFERENCES option will tell the database engine that table2.userid requires that a row exist in table1 such that table1.userid = table2.userid. The ON DELETE and ON UPDATE clauses will cause the deletion of a row in table1 to automatically delete/update rows in table2.
You cannot create a row in table2 until you have created a row for the user in table1. The row in table1 will auto-generate the userid. When you insert into table2, you will explicitly include the user id from table1 to establish the linkage between the rows.
If the userid field on table2 is not autoincrement then you have to provide the value or the insert will fail.
If you have defined userID in table2 as foriegn key constraint, then you will need to have the corresponding userID in the table1 as reference when inserting rows to table2, else if you have not defined any such constraints, then it will not matter.
Keep in mind, if the constraint is defined, then table2 will not generate ID by itself. It would require the ID to be present in the table1 column which is referenced.
If username and password is not null then don't insert in tabel 1 and give error