views:

440

answers:

3

I'm trying to use SqlBulkCopy to insert new rows into my DB table by manually populating a DataTable w/in my application.

This works fine for all tables except the table that has a composite primary key made up of 3 columns. Whenever I try to SqlBulkCopy anything into this table, I get the following error:

Violation of PRIMARY KEY constraint 'PK_MYCOMPOSITEKEY'. Cannot insert duplicate key in object 'dbo.MyTable'.
The statement has been terminated.

Is this even possible?

I have tried setting up my DataTable's primary keys with the following:

dt.PrimaryKey = new[] {dt.Columns["PKcolumn1"], dt.Columns["PKcolumn2"], dt.Columns["PKcolumn3"]};

but again, no luck.

+1  A: 

The problem you have is with the data.

In the input file there is either or both of

a row which has the same data in the e pk columns as you already have in the table

or

The file has at least two rows with the same values of the pk columns

Mark
That's what I thought too. However, I have limited the insertion to a single row of values that I **know** are not yet in the database table.
kamens
The datbase thinks they are - what are the values ?
Mark
You and Majkara are correct. I am using Linq-to-SQL, and a foreign key dependency was being walked during DB.SubmitChanges() that inserted these foreign rows ahead of the SqlBulkCopy in my path of execution...even though I hadn't explicitly added the rows themselves.
kamens
A: 

Bulk insert to a staging table. Clean up any duplicate records. Then do an insert using straight SQL. When you write the insert code be sure to limit it to records in the staging table that are not in the prod table.

HLGEM
+1  A: 

You should verify your bulk data for copies before you hit the DB, the problem could be there as well (not just clashing with an existing constraint, or record in DB). It does work and it is usually correct to report it.

Nonetheless, the entire show of DataSet or even DataReaders is a messy exercise in mappings, bad typeless design, plenty of unnecessary transformations, allocations, object[] based values, and the entire thing becomes order, type and string dependent mess (something only MS could design and keeps designing). Native OLEDB bulk interfaces on the other hand are much cleaner.

rama-jka toti