I am trying to use UPSERT in postgresql. Below is my SQL string.
INSERT INTO dashboard.tblpurchaseordermaster (po_number,"po_created_TS",
vendor_code,"Refreshed_Datetime",
"Is_PO_Closed","PO_Closed_Date","TenderID","POVendorTender")
SELECT po_number,CAST("po_created_TS" AS date),vendor_code,current_timestamp,
"Is_PO_Closed","PO_Closed_Date",
"TenderID",
CONCAT(po_number,vendor_code,CAST("TenderID" AS varchar)) AS "POVendorTender"
FROM pomaster_temp
ON CONFLICT ("POVendorTender") WHERE ("POVendorTender" NOTNULL)
DO UPDATE SET "po_created_TS" = EXCLUDED."po_created_TS",
"Is_PO_Closed"=EXCLUDED."Is_PO_Closed",
"PO_Closed_Date"=EXCLUDED."PO_Closed_Date";
I am getting an error as
21000-ON CONFLICT DO UPDATE command cannot affect row a second timeON CONFLICT DO UPDATE
command cannot affect row a second time--Ensure that no rows proposed for insertion within the
same command have duplicate constrained values.-
Not able to figure out where I am missing?
P.S: POVendorTender is an Index key and being generated as combination of po_number, vendor_code and TenderID.
ON CONFLICT:
INSERT with an ON CONFLICT DO UPDATE clause is a “deterministic” statement. This means that the command will not be allowed to affect any single existing row more than once; a cardinality violation error will be raised when this situation arises. Rows proposed for insertion should not duplicate each other in terms of attributes constrained by an arbiter index or constraint.
When the rows are INSERTed in a single statement, then the above applies.
Related
I am trying to update one row of the storeID column. When I do the first code below, it runs but will not affect any row. However, the bottom two are producing the following error " The UPDATE statement conflicted with the REFERENCE constraint "Products_FK". The conflict occurred in database "group7", table "dbo.Products", column 'storeID'."
Could anyone help? Thanks!
Table in SQL
UPDATE Store
SET storeID='E50'
WHERE storeID='D50'
AND storeID is Null;
UPDATE Store
SET storeID='E50'
WHERE storeID='D50'
UPDATE Store
SET storeID='E50'
WHERE storeName='A Plus Cables'
Above is the code that I have tried and nothing is being updated.
The first one can't possibly match any rows, because a single value can't equal two different things at the same time:
WHERE storeID='D50'
AND storeID is Null
So that one is kind of a moot point. You'd need to update the WHERE clause to target the record(s) you want to target.
For the latter two, the error is telling you what's wrong. You're trying to write this value to a column:
SET storeID='E50'
But the error is telling you:
That column is a foreign key to another table. (Products?)
The value you're writing isn't presentin that other table.
So your options are:
Use a value that is present in the other table.
Use NULL (and update the column to allow NULL if necessary).
Remove the foreign key constraint to that other table.
I have two tables:
assignments {recceptacleId, assignedCarrier}
rls_permissions {receptacleId, rlsUserId}
An assignment in this context is any receptacle to airline carrier relationship.
Whenever a new assignment comes into the assignments table, I'd like to upsert (insert if new row or update if it's an existing receptacle being assigned to a new airline carrier) my rls_permissions table.
The issue I'm having with upsert, specifically ON CONFLICT ON CONSTRAINT, is that my insert statement contains a sub-query for the data to be inserted and therefore I'm not sure how to write the DO UPDATE SET part of the statement
I've tried using 'excluded' to try and single out the assignedCarrier that I want to update based on the previous conflict however I keep receiving "ERROR: column excluded.receptacleId does not exist"
My pkey looks like this:
CREATE UNIQUE INDEX rls_permissions_pkey ON rls_permissions("receptacleId" text_ops);
Dummy data could be:
receptacleID assignedCarrier
aaaaaaaaaa00 AA
Where AA is "American Airlines"
INSERT INTO rls_permissions ("receptacleId","rlsUserId")
SELECT DISTINCT assignments."receptacleId", assignments."assignedCarrier"
FROM assignments
ON CONFLICT ON CONSTRAINT rls_permissions_pkey
DO UPDATE SET "rlsUserId" = (SELECT DISTINCT assignments."assignedCarrier"
FROM assignments
WHERE assignments."receptacleId" = excluded."receptacleId");
The excepted result is that if no conflict, the data returned from the sub-query is inserted into a new row on the permissions table.
If there is a conflict, I'd like to update ONLY the newly assigned carrier, and not update or insert a new line since that receptacle already exists.
You don't need a subquery in the UPDATE part. You can access the values for the INSERT part through the excluded keyword.
INSERT INTO rls_permissions ("receptacleId","rlsUserId")
SELECT DISTINCT assignments."receptacleId", assignments."assignedCarrier"
FROM assignments
ON CONFLICT ON CONSTRAINT rls_permissions_pkey
DO UPDATE SET "rlsUserId" = excluded."rlsUserId";
the reference to excluded."rlsUserId" refers to the value that would have been inserted into the column rlsUserId and thus it's the value retrieved through assignments."assignedCarrier" from your SELECT statement.
I have the following sql code:
UPDATE google_calendar_accounts SET google_refresh_token="d",google_org_token="d" WHERE userID=5;
IF ROW_COUNT()=0 THEN
INSERT INTO google_calendar_accounts (userID,google_refresh_token,google_org_token) VALUES (5,"d","d"); END IF
and I am getting the error:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 2
I am using mariadb 10.1.14
In spite the comment suggesting to do INSERT ... ON DUPLICATE KEY UPDATE ..., There may be a reason to do the update first, and insert just if there was no row affected, like the OP tried: this way auto increment won't be increased in vain.
So, a possible solution to the question may be using insert from select with a condition where row_count()=0
For example:
--first query
UPDATE google_calendar_accounts
SET google_refresh_token='d',google_org_token='d'
WHERE userID=5;
--second query use the affected rows of the previous query
INSERT IGNORE INTO google_calendar_accounts (userID,google_refresh_token,google_org_token)
SELECT 5,'d','d' WHERE ROW_COUNT()=0
BTW: I've added IGNORE to the insert query for a case there was a row match to the update condition but it wasn't updated since all columns was identical to the updated, like in the case before the update there was already row 5,'d','d'.
In such case, if the 5 is primary or unique key the query won't fail.
Trying insert table data into another table,
But I'm getting the following error:
Msg 2627, Level 14, State 1, Line 4
Violation of PRIMARY KEY constraint 'PK___4__10'. Cannot insert duplicate key in object 'dbo.tbl_Diagnosis_Table'.
Appears to be a duplicate primary key between both tables. Both tables have the same fields and data types, different data. What query can resolve this issue?
INSERT INTO tbl_Diagnosis_Table
SELECT *
FROM tbl_Holding_Diagnosis_Table
INSERT INTO tbl_Diagnosis_Table(Code, [Description], Comments, Discontinued)
(SELECT
Code, [Description], Comments, Discontinued
FROM
tbl_Holding_Diagnosis_Table);
Assuming Code is the primary key this should eliminate the duplicate rows from the insert:
INSERT INTO tbl_Diagnosis_Table (Code, [Description], Comments, Discontinued)
SELECT Code, [Description], Comments, Discontinued
FROM tbl_Holding_Diagnosis_Table
WHERE tbl_Holding_Diagnosis_Table.Code NOT IN
(SELECT Code FROM tbl_Diagnosis_Table)
If the primary key is some other column, or a composite key, you might need to use a join instead.
You might want to look at the MERGE statement if you want to update existing rows and only insert new.
You need a WHERE with an IN Clause To filter the records to insert, but first you need to know wich fields form the primary key.
If what you're saying is correct i.e. all the values are unique, it leaves only one option. Make sure that if there is an identity column in table tbl_diagnosis_table, you are setting the IDENTITY_INSERT to ON on this table and providing values manually in the select. It might have been possible that the seed and increment was reset in the past. In case you were wrong, you have to use a where clause as suggested by others.
I was going to suggest using a Merge query to do insert or update until I noticed the two inserts in the sample code both do the same insert. The error also says the error is on line 4 which is where the second insert occurs. If the two inserts aren't two examples of the problematic code, then the resolution may be as simple as removing one of the inserts.
Otherwise the other answers are correct, the duplicate rows need to be filtered and the IDENTITY_INSERT has to be turned on for the table.
SET IDENTITY_INSERT tbl_Diagnosis_Table ON -- if it is necessary to have the same primary key
MERGE tbl_Diagnosis_Table AS target
USING (SELECT Code, Description, Comments, Discontinued FROM tbl_Holding_Diagnosis_Table) AS source (Code, Description, Comments, Discontinued)
ON (target.Code = source.Code)
WHEN MATCHED THEN
UPDATE SET Description = source.Description,
Comments = source.Comments,
Discontinued = source.Discontinued
WHEN NOT MATCHED THEN
INSERT (Code, Description, Comments, Discontinued)
VALUES (source.Code, source.Description, source.Comments, source.Discontinued)
END; -- missing semicolons causes errors
SET IDENTITY_INSERT tbl_Diagnosis_Table OFF
Do your homework though. There are some very good reasons not to use Merge.
Use Caution with SQL Server's MERGE Statement
Indexed views and Merge
Optimizing Merge Statement Performance
Is there a way to overwrite or skip duplicate records?
1062 - Duplicate entry '2' for key 1
is there a way to add : insert on duplicate key update to a sql file that only has insert?
Have a look at 12.2.5.1. INSERT ... SELECT Syntax and 12.2.5. INSERT Syntax
And look for
Specify IGNORE to ignore rows that
would cause duplicate-key violations.
try this:
INSERT ON DUPLICATE KEY UPDATE
Although usually people forget to put the autoincrement field for the id and thus the error.