Getting 'Cannot insert duplicate key' from UPDATE query - c++

I'm writing an ODBC class to connect to a remote SQL Server database. I have most of it working.
The class has the ability to generate queries such as the following:
UPDATE Customers SET Id=?,Name=?,TaxId=?,ContactFName=?,ContactLName=?,Phone_Office=?,Phone_Mobile=?,Phone_Home=?,Email=?,Website=?,Address1_Physical=?,Address2_Physical=?,City_Physical=?,State_Physical=?,Zip_Physical=?,Address1_Billing=?,Address2_Billing=?,City_Billing=?,State_Billing=?,Zip_Billing=?,StartingBalance=?,Discount=?,BillingSequence=?,BillingCategory=?,ShowOnReport=?,Active=?,CreateDate=?
As you can see, it's an UPDATE query. Yet, running this query gives me an error:
Microsoft ODBC Driver 17 for SQL Server (SQL Server) : ReturnCode: -1 : Violation of PRIMARY KEY constraint 'PK_Customers'. Cannot insert duplicate key in object 'dbo.Customers'. The duplicate key value is (82). (State: 23000, NativeError: 2627) : The statement has been terminated. (State: 01000, NativeError: 3621)
I'm confused why I'm getting an error about inserting when I'm doing an update. Has anyone seen this?
Notes:
Id is the primary key. I first read all column values from the database, and then update those I want to change. The ID does not change.
The error above was put together by my code, but is based on the messages returned by SQLGetDiagRec().

There's no WHERE clause on the UPDATE statement, so it's trying to update EVERY SINGLE ROW in the database, and since ID is one of the columns being changed, it's trying to set every row's ID to the same value. This is resulting in an attempt to create a duplicate primary key.
Make sure your UPDATE statement has an appropriate WHERE clause... like "WHERE ID = ?"... and it's probably best practice to NOT include the ID in that UPDATE statement if it's not changing.

That is the message you should expect when an UPDATE statement violates a primary key. EG
use tempdb
go
drop table if exists t
create table t(id int primary key)
insert into t(id) values (1),(2)
go
update t set id = 2 where id = 1
--Msg 2627, Level 14, State 1, Line 11
--Violation of PRIMARY KEY constraint 'PK__t__3213E83F127C5D76'. Cannot insert duplicate key in object 'dbo.t'. The duplicate key value is (2).
--The statement has been terminated.

In the UPDATE I see a field called ID. If you are making a change to the ID and it's the primary key then the DBMS will fuss because you are trying to store duplicate keys.

Related

DynamoDB PutItem keeps overwriting previous entry

I want to put an order from my lex bot into dynamoDB however the PutItem operation overwrites each time(If the customer name is already in the table).
I know from the documentation that it will do this if the primary key is the same.
My goal is to have each order put into the database so they will be easily searchable in the future.
I have attached some screenshots below. Any help is appreciated
https://imgur.com/a/mLpEkOi
def putDynam(orderNum, table_custName, slotKey, slotVal):
client = boto3.resource('dynamodb')
table = client.Table('blah')
input = {'Customer': table_custName, 'OrderNumber':orderNum[0], 'Bun Type': slotVal[5], 'CheeseDecision': slotVal[1], 'Cheese Type': slotVal[0], 'Pickles': slotVal[4], 'SauceDecision': slotVal[3], 'Sauce Type': slotVal[2]}
action = table.put_item(Item=input)
The primary key is used for identifying each item in the table. There can only be 1 record with a specific primary key (primary keys are unique).
Customer name is not a good primary key, because it's not unique.
In this case you could have an order with some generated Id (orderNumber in your example?), that could be the primary key, and Customer (preferably CustomerId) as a property.
Or you could have a composite primary key made up of CustomerId and OrderId.
If you want to query orders by customer, you could use an index if it's not in the primary key.
I recommend you read up on how DynamoDB works first. You can start with this data modelling tutorial from AWS.
So, basically, the customer name has to be unique, since it's your Primary Key. You can't have two rows with the same primary key. A way could be to have an incremental value that serves as id, and each insert would simply have i+1 as its id.
You can see this stack overflow question for more information: https://stackoverflow.com/a/12460690/11593346
Per https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.put_item, you can:
"perform a conditional put operation (add a new item if one with the specified primary key doesn't exist)"
Note
To prevent a new item from replacing an existing item, use a conditional expression that contains the attribute_not_exists function with the name of the attribute being used as the partition key for the table. Since every record must contain that attribute, the attribute_not_exists function will only succeed if no matching item exists.
Also see DynamoDB: updateItem only if it already exists
If you really need to know whether the item exists or not so you can trigger your exception logic, then run a query first to see if the item already exists and don't even call put_item. You can also explore whether using a combination of ConditionExpression and one of the ReturnValues options (for put_item or update_item) may return enough data for you to know if an item existed.

Update Else Insert without Update Strategy

I'm inserting from a source table to the target table. If the source record already exists in the target, then it will update else insert. I have done this without using Update strategy. In session properties, I have set as treat rows as 'Update' and in the mapping target properties, I selected 'Insert' and 'Update Else Insert' checkbox. Also, I have chosen a primary key in the target table as well. But while running the session every time, it is always inserting the same rows again and again. I.e. duplicate rows are inserting instead of update the record. am I doing anything wrong?
The database table should have primary keys defined for this to work.

Unable to add duplicate entry through informatica

I am using Informatica to finally write in the oracle table after performing certain logical operations on the data.
The problem is that if a certain ID was already previously processed and is present in the target table then it is not inserted again.
Please suggest a workaround.
Hi, This is because you might have same primary key in the source which is available in the target. Look into primary key columns and try loading them.
Altering your target table
alter table target_table_name drop constraint constraint name;

Error while updating a record in APEX screen

while updating a record using MRU its failing with below error.
1 error has occurred
Current version of data in database has changed since user initiated update process. current row version identifier = "C5F3645B026AA5646C00DC7B631C4D19" application row version identifier = "6A9323B62F641015FA4601421DFB03DE" (Row 1)
This is strange because I do not see any change in the data at backend.
Any help will be highly appreciated.
Thanks.
AJ
If you're using a tabular form, check your query, then check the item. The item must match with the correct column in a database that is updatable.
Make sure that your column aliases match your column names (for updateable columns).
I had the same problem, the problem in my case that detail table has composite primary key,
so in application > column > Primary KeyPrimary Key
property must all primary key field enable , not only one field.

Siebel Operation Error for Inserting Field based on picklist

I am facing an issue where I am getting the below error while inserting a record in the table via Siebel Operation step.
Here the error is showing for field which is based on a picklist. Could anyone please suggest why i am getting this error:
SBL-DAT-00225: The value entered in field District of buscomp Contact_Address_LT does not match any value in the bounded pick list PickList Comm Resolution.
SBL-BPR-00100: This error is returned when the workflow/task is executing the Siebel Operation business service.
I am aware that this happens when the value is not defined in the picklist. But i have verified this, and LOV is having the value which I am trying to get insert.
This error is quite common. And could happen for a couple of reason.
As you have mentioned, that you have already checked the value which is getting inserted is already there in the LOV defined for the picklist.
I have recently faced this error, and spent hours to debug it. Try below to sort your problem.
Check for the below points:
1) Check for the pick map for this field, check if any contraint field is also present in it.
2) If yes, then check those constraint field is also getting inserted in same Siebel Operation step. Siebel does not follow sequence in the input argument. So if this is the case do step 3 to resolve your issue.
3) Split the insert statement into 2 parts, 1 where you insert the record with the values which is present in the pick map constraint and then update the same record. This will ensure that all the required field are populated.
Solution from 8.1.1.4 is to add parameter into OM's config file, e.g fins.cfg:
[Task]
ProcessArgAsc = true
More details in my oracle support.