SQL Statement Error table to table - sql

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

Related

Is there an elegant way to deal with inserting rows with duplicate identifiers?

I'm trying to insert some rows into my table that have the same unique identifier, but all the other fields are different (the rows represent points on a map, and they just happen to have the same name). The final result I'd like to end up with is to somehow modify the offending rows to have unique identifiers (adding on some incrementing number to the identifier, like "name0", "name1", "name2", etc.) during the insertion command.
I'm aware of Postgres's recent addition of "ON CONFLICT" support, but it's not quite what I'm looking for.
According to the Postgres 9.6 Documentation:
The optional ON CONFLICT clause specifies an alternative action to raising a unique violation or exclusion constraint violation error. For each individual row proposed for insertion, either the insertion proceeds, or ... the alternative conflict_action is taken. ...ON CONFLICT DO UPDATE updates the existing row that conflicts with the row proposed for insertion as its alternative action.
What I would like to do is 1) either modify the offending row or the insertion itself and 2) proceed with the insertion (instead of replacing it with an update, like the ON CONFLICT feature does). Is there an elegant way of accomplishing this? Or am I going to need to write something more complex?
You can do this:
create table my_table
(
name text primary key,
some_column varchar
);
create sequence my_table_seq;
The sequence is used to assign a unique suffix to the new row's PK column.
The "insert on conflict insert modified" behaviour can be done like this:
with data (name, some_column) as (
values ('foo', 'bar')
), inserted as (
insert into my_table
select *
from data
on conflict (name) do nothing
returning *
)
insert into my_table (name, some_column)
select concat(name, '_', nextval('my_table_seq')), some_column
from data
where not exists (select 1 from inserted);
The first time you insert a value into the PK column, the insert (in the CTE "inserted") just proceeds. The final insert won't insert anything because the where not exists () prevents that as the inserted returned one row.
The second time you run this, the first insert won't insert anything, and thus the second (final) insert will.
There is one drawback though: if something was inserted by the "inserted" CTE, the the overall statement will report "0 rows affected" because the final insert is the one "driving" this information.

An UPDATE or INSERT statement attempted to insert a duplicate key

I am trying to use this query to update a table wherein I am adding a new musician named Helen Partou who has recently learnt how to play the tambourine adequately. Here is the query:
merge into MusicianInstrument i
using Musician m
on (m.musicianNo = i.musicianNo
and i.instrumentName = 'Tambourine'
and m.musicianName = 'Helen Partou')
when matched then update set levelOfExpertise = 'Adequate'
when not matched then insert (i.musicianNo, i.instrumentName, i.levelOfExpertise)
values (m.musicianNo, 'Tambourine', 'Adequate');
However, this error keeps appearing:
An UPDATE or INSERT statement attempted to insert a duplicate key.
There is no existing key as the error may suggest. Here is the original insert into statements with data specific to each musician:
insert into MusicianInstrument(musicianNo,instrumentName,levelOfExpertise)
values('04','Saxophone','Expert');
insert into MusicianInstrument(musicianNo,instrumentName,levelOfExpertise)
values('04','Harp','Average');
Since the MusicianInstrument table does not contain any detail about Helen learning the Tambourine at an Adequate level, the merge into statement should update the table with this information.
Why am I getting this error? The RDBMS I am currently using is Oracle. Any help would be appreciated greatly!
Thanks.

INSERT INTO SELECT FROM doesnt work. Not even an error

INSERT INTO kid_progress_Backup (userid)
SELECT id
FROM users1
WHERE id>770
I am a newbie but I copied and pasted then tried on my sqlite tables.
id is the autoincrement so maybe there is a problem there. I also tried changing id and using another column but that doesnt work either.
An error didnt even pop up- which is really weird.
Basically I have two tables. I have added records to the first and now I want to add that nuber of records to the other table. The relationship of keys is users1.id to kid_progress_Backup.userid. Then I need to add/chabge values in the kid_progress_Backup table according to some values in the users1 table. First I am just trying to add the same amount of new records than I was going to do a UPDATE and SET.
Your problem may be occurred, because there are some other fields in kid_progress_Backup, which can't be NULL and does not have default values.
If you use SQLite, then you should use INSERT OR REPLACE statement for your case. So, you will not need an UPDATE. But you should define PRIMARY KEY or UNIQUE INDEX on userid column.
Try this SQL Query
SET IDENTITY_INSERT kid_progress_Backup ON
INSERT INTO kid_progress_Backup (userid)
SELECT id
FROM users1
WHERE id>770
SET IDENTITY_INSERT kid_progress_Backup OFF
try somethinglike this:
INSERT INTO kid_progress_Backup(userid) VALUES(SELECT id FROM users1 WHERE id>770);

How to find the error value in sql table

I am inserting values from one table to another table. There are 100000 records in the table. But when I start to insert value from one table to another table there is a problem in any row in my data. I don't know where exactly is that. So how can I know that in which row value is error because the insert statement not complete? After error this stop nothing insert in table.
This is simple statement that I use:
INSERT INTO Person (FirstName, LastName,Email)
SELECT FirstName, LastName, Email
FROM Person.Contact
Without any additional information on the constraints imposed on the target table a very general, slow solution would be
a cursor loop over the selected rows
insert any row within try/catch
on exception output row and error message
For a specific answer to your problem provide more information.
An alternative method is to use SSIS: here you can provide a separate channel for the erroneous rows. This channel can be lead to a separate table collecting all rows causing an error.
quesion is hard to understand, but the usual suspects are:
Attempting to insert Null into a non-nullable column
Foreign Key violations
Constraint violations.
Attempting to insert wrong datatype.
Please edit you question to add error message.
I guess Person is the name of your schema, so maybe you mean
INSERT INTO Person.Person (FirstName, LastName,Email)
SELECT FirstName, LastName, Email
FROM Person.Contact

SQLite insert or select primary key

I want to insert a row if it doesn't already exist. If it does already exist, I want to get it's primary key.
Can this be done without using two queries, for instance using a UNIQUE constraint on the columns and ON CONFLICT ... TELL ME THE CONFLICTING ROWID?
Please note that I don't have experience with SQLite. However, after perusing the online documentation, I don't believe that it supports data-change table references, so no, this isn't possible.
My reccommendation is to write your INSERT in such a way that it won't fail if the row exists - it just won't insert a row. Something like this:
INSERT INTO destinationTable (colA, colB)
(SELECT :colAValue, :colBValue
WHERE NOT EXISTS (SELECT '1'
FROM destinationTable
WHERE uniqueColumn = :uniqueColumn))
This works because the selection won't return a row if it already exists. You can then either look at the return code/state to see if it INSERTed a row, or just SELECT with the unique column, to get the identity column.
DON'T rely on your constraint to catch this. Constraints are to catch application errors, and this is solely a business/implementation detail.
In a word, no. You can't, with SQLite, either INSERT data or, on some condition, SELECT it.
Other SQL engines might allow it, but SQLite can't.
What you can do is INSERT OR IGNORE, which will just not bring up an error. See http://sqlite.org/lang_conflict.html