How to get the ignored row while IGNORE_DUP_KEY is ON on SQL Server?
I have a tmp
table shown below.
In the above table
IGNORE_DUP_KEY
is set toON
and
- the
id
column is the primary key.
Said table has only one key. After inserting lots of data I will get the
Duplicate key was ignored.
message because of some redundant data.
I want to check which redundant row was tried to insert. I checked the origin of the message it was sys.messages
.
Now, how to store the row which failed while the insertion attempt took place because of the duplicate primary key value?
sql-server primary-key
New contributor
add a comment |
I have a tmp
table shown below.
In the above table
IGNORE_DUP_KEY
is set toON
and
- the
id
column is the primary key.
Said table has only one key. After inserting lots of data I will get the
Duplicate key was ignored.
message because of some redundant data.
I want to check which redundant row was tried to insert. I checked the origin of the message it was sys.messages
.
Now, how to store the row which failed while the insertion attempt took place because of the duplicate primary key value?
sql-server primary-key
New contributor
add a comment |
I have a tmp
table shown below.
In the above table
IGNORE_DUP_KEY
is set toON
and
- the
id
column is the primary key.
Said table has only one key. After inserting lots of data I will get the
Duplicate key was ignored.
message because of some redundant data.
I want to check which redundant row was tried to insert. I checked the origin of the message it was sys.messages
.
Now, how to store the row which failed while the insertion attempt took place because of the duplicate primary key value?
sql-server primary-key
New contributor
I have a tmp
table shown below.
In the above table
IGNORE_DUP_KEY
is set toON
and
- the
id
column is the primary key.
Said table has only one key. After inserting lots of data I will get the
Duplicate key was ignored.
message because of some redundant data.
I want to check which redundant row was tried to insert. I checked the origin of the message it was sys.messages
.
Now, how to store the row which failed while the insertion attempt took place because of the duplicate primary key value?
sql-server primary-key
sql-server primary-key
New contributor
New contributor
edited 36 mins ago
MDCCL
6,69731744
6,69731744
New contributor
asked 7 hours ago
V T VishwanathV T Vishwanath
1284
1284
New contributor
New contributor
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You could capture all the PK exceptions using a trace or you could capture which sql statements trigger the duplicate key message with an extended event.
In the following examples it shows you how to either capture the 'Exception' with a profiler trace, or capture the sql text executed that triggers the duplicate key message using an extended event.
The difference being that the 'exception' trace gets a row for each violation, which we could log to a file, and then read from that file.
What could you capture?
Before the user error message is returned,a PK violation occurs internally:
Which in turns gives the duplicate key value:
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
While the user does not see this message, we could either capture these with a trace or an extended event.
Profiler trace on the exceptions on the table
Add a filter
Capture the PK violations, even when IGNORE_DUP_KEY = ON
Error message captured
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
The problem here is that it can get messy real fast, as it gives a record per Failed value, so if 1 and 2 already exist
INSERT INTO ignore_dup_key(a) VALUES(1), (2)
It gives two new exceptions in the profiler trace:
1)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
2)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (2).
Saving it to a table
Select from the new table
SELECT *
FROM [my_test].[dbo].[FindViolations];
So, when Inserting 1000 Duplicate ID's, the logging will hold 1000 extra records
TRUNCATE TABLE [my_test].[dbo].[FindViolations];
INSERT INTO ignore_dup_key(a)
select a from ignore_dup_key; -- 1000 duplicate records
SELECT COUNT(*) from [my_test].[dbo].[FindViolations];
Result
(No column name)
1000
ETC.
Create the extended event
Do not choose a template
Select the error_reported event
Select the SQL_TEXT and username, and any additional things you would want to capture
Result
You could also add a filter, as to filter out non-duplicate key errors
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
add a comment |
There would be additional overhead, but one option might be to create an instead of insert
trigger which would check for duplicates first and route those to another table.
--demo setup
set nocount on
DROP TABLE IF EXISTS [dbo].[TestTable]
CREATE TABLE [dbo].[TestTable](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL,
CONSTRAINT [PK_Employee_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
) with (IGNORE_DUP_KEY = ON)
) ON [PRIMARY]
GO
DROP TABLE IF EXISTS [dbo].[TestTableIgnoredDups]
CREATE TABLE [dbo].[TestTableIgnoredDups](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL
)
ON [PRIMARY]
GO
--create INSTEAD OF trigger
CREATE TRIGGER TestTable_InsteadOfInsert ON dbo.TestTable
INSTEAD OF INSERT
AS
BEGIN
--select rows to be inserted into #temp
SELECT *
INTO #temp
FROM inserted
--insert rows to TestTableIgnoredDups where primary key already exists
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--delete the duplicate rows from #temp
DELETE t
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--insert rows to TestTableIgnoredDups where duplicates
--exist on the inserted virtual table, but not necessarily on TestTable
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.id;
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
DELETE t
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.ID
--insert the remaining rows to TestTable
INSERT INTO TestTable
SELECT *
FROM #temp
END
GO
--verify by trying to insert a duplicate row
insert into testtable(id,ExtraInformation) values(1,'RowOne')
insert into testtable(id,ExtraInformation) values(1,'RowOneDup')
select * from TestTable
select * from TestTableIgnoredDups
Data from TestTable
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOne |
Data from TestTableIgnoreDups
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOneDup |
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with aninstead of
trigger.
– Scott Hodgin
4 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
V T Vishwanath is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f227267%2fhow-to-get-the-ignored-row-while-ignore-dup-key-is-on-on-sql-server%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could capture all the PK exceptions using a trace or you could capture which sql statements trigger the duplicate key message with an extended event.
In the following examples it shows you how to either capture the 'Exception' with a profiler trace, or capture the sql text executed that triggers the duplicate key message using an extended event.
The difference being that the 'exception' trace gets a row for each violation, which we could log to a file, and then read from that file.
What could you capture?
Before the user error message is returned,a PK violation occurs internally:
Which in turns gives the duplicate key value:
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
While the user does not see this message, we could either capture these with a trace or an extended event.
Profiler trace on the exceptions on the table
Add a filter
Capture the PK violations, even when IGNORE_DUP_KEY = ON
Error message captured
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
The problem here is that it can get messy real fast, as it gives a record per Failed value, so if 1 and 2 already exist
INSERT INTO ignore_dup_key(a) VALUES(1), (2)
It gives two new exceptions in the profiler trace:
1)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
2)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (2).
Saving it to a table
Select from the new table
SELECT *
FROM [my_test].[dbo].[FindViolations];
So, when Inserting 1000 Duplicate ID's, the logging will hold 1000 extra records
TRUNCATE TABLE [my_test].[dbo].[FindViolations];
INSERT INTO ignore_dup_key(a)
select a from ignore_dup_key; -- 1000 duplicate records
SELECT COUNT(*) from [my_test].[dbo].[FindViolations];
Result
(No column name)
1000
ETC.
Create the extended event
Do not choose a template
Select the error_reported event
Select the SQL_TEXT and username, and any additional things you would want to capture
Result
You could also add a filter, as to filter out non-duplicate key errors
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
add a comment |
You could capture all the PK exceptions using a trace or you could capture which sql statements trigger the duplicate key message with an extended event.
In the following examples it shows you how to either capture the 'Exception' with a profiler trace, or capture the sql text executed that triggers the duplicate key message using an extended event.
The difference being that the 'exception' trace gets a row for each violation, which we could log to a file, and then read from that file.
What could you capture?
Before the user error message is returned,a PK violation occurs internally:
Which in turns gives the duplicate key value:
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
While the user does not see this message, we could either capture these with a trace or an extended event.
Profiler trace on the exceptions on the table
Add a filter
Capture the PK violations, even when IGNORE_DUP_KEY = ON
Error message captured
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
The problem here is that it can get messy real fast, as it gives a record per Failed value, so if 1 and 2 already exist
INSERT INTO ignore_dup_key(a) VALUES(1), (2)
It gives two new exceptions in the profiler trace:
1)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
2)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (2).
Saving it to a table
Select from the new table
SELECT *
FROM [my_test].[dbo].[FindViolations];
So, when Inserting 1000 Duplicate ID's, the logging will hold 1000 extra records
TRUNCATE TABLE [my_test].[dbo].[FindViolations];
INSERT INTO ignore_dup_key(a)
select a from ignore_dup_key; -- 1000 duplicate records
SELECT COUNT(*) from [my_test].[dbo].[FindViolations];
Result
(No column name)
1000
ETC.
Create the extended event
Do not choose a template
Select the error_reported event
Select the SQL_TEXT and username, and any additional things you would want to capture
Result
You could also add a filter, as to filter out non-duplicate key errors
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
add a comment |
You could capture all the PK exceptions using a trace or you could capture which sql statements trigger the duplicate key message with an extended event.
In the following examples it shows you how to either capture the 'Exception' with a profiler trace, or capture the sql text executed that triggers the duplicate key message using an extended event.
The difference being that the 'exception' trace gets a row for each violation, which we could log to a file, and then read from that file.
What could you capture?
Before the user error message is returned,a PK violation occurs internally:
Which in turns gives the duplicate key value:
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
While the user does not see this message, we could either capture these with a trace or an extended event.
Profiler trace on the exceptions on the table
Add a filter
Capture the PK violations, even when IGNORE_DUP_KEY = ON
Error message captured
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
The problem here is that it can get messy real fast, as it gives a record per Failed value, so if 1 and 2 already exist
INSERT INTO ignore_dup_key(a) VALUES(1), (2)
It gives two new exceptions in the profiler trace:
1)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
2)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (2).
Saving it to a table
Select from the new table
SELECT *
FROM [my_test].[dbo].[FindViolations];
So, when Inserting 1000 Duplicate ID's, the logging will hold 1000 extra records
TRUNCATE TABLE [my_test].[dbo].[FindViolations];
INSERT INTO ignore_dup_key(a)
select a from ignore_dup_key; -- 1000 duplicate records
SELECT COUNT(*) from [my_test].[dbo].[FindViolations];
Result
(No column name)
1000
ETC.
Create the extended event
Do not choose a template
Select the error_reported event
Select the SQL_TEXT and username, and any additional things you would want to capture
Result
You could also add a filter, as to filter out non-duplicate key errors
You could capture all the PK exceptions using a trace or you could capture which sql statements trigger the duplicate key message with an extended event.
In the following examples it shows you how to either capture the 'Exception' with a profiler trace, or capture the sql text executed that triggers the duplicate key message using an extended event.
The difference being that the 'exception' trace gets a row for each violation, which we could log to a file, and then read from that file.
What could you capture?
Before the user error message is returned,a PK violation occurs internally:
Which in turns gives the duplicate key value:
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
While the user does not see this message, we could either capture these with a trace or an extended event.
Profiler trace on the exceptions on the table
Add a filter
Capture the PK violations, even when IGNORE_DUP_KEY = ON
Error message captured
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
The problem here is that it can get messy real fast, as it gives a record per Failed value, so if 1 and 2 already exist
INSERT INTO ignore_dup_key(a) VALUES(1), (2)
It gives two new exceptions in the profiler trace:
1)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (1).
2)
Violation of PRIMARY KEY constraint 'PK__ignore_d__3BD0198E9F9BACEA'. Cannot insert duplicate key in object 'dbo.ignore_dup_key'. The duplicate key value is (2).
Saving it to a table
Select from the new table
SELECT *
FROM [my_test].[dbo].[FindViolations];
So, when Inserting 1000 Duplicate ID's, the logging will hold 1000 extra records
TRUNCATE TABLE [my_test].[dbo].[FindViolations];
INSERT INTO ignore_dup_key(a)
select a from ignore_dup_key; -- 1000 duplicate records
SELECT COUNT(*) from [my_test].[dbo].[FindViolations];
Result
(No column name)
1000
ETC.
Create the extended event
Do not choose a template
Select the error_reported event
Select the SQL_TEXT and username, and any additional things you would want to capture
Result
You could also add a filter, as to filter out non-duplicate key errors
edited 4 hours ago
answered 5 hours ago
Randi VertongenRandi Vertongen
1,703314
1,703314
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
add a comment |
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
Can we capture for a specific database and table?
– V T Vishwanath
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the profiler trace window you can add additional filters, this is located at events selection --> Column Filters... . There you can add a databasename, and the table filter needs to be added to the TextData filter
– Randi Vertongen
5 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
In the case of Extended Events. What if we have bulk insertion ? or using BCP? How to get the exact record which failed. I tried with multiple insert statements and it gives all sql text. Can't find the exact insert statement which failed.
– V T Vishwanath
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
@VTVishwanath For the moment being I have not found the correct event for capturing all the different failed records, only the statement executed. For now, only by using the profiler trace and logging it to a table was I able to get all the records that failed through T-SQL.
– Randi Vertongen
4 hours ago
add a comment |
There would be additional overhead, but one option might be to create an instead of insert
trigger which would check for duplicates first and route those to another table.
--demo setup
set nocount on
DROP TABLE IF EXISTS [dbo].[TestTable]
CREATE TABLE [dbo].[TestTable](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL,
CONSTRAINT [PK_Employee_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
) with (IGNORE_DUP_KEY = ON)
) ON [PRIMARY]
GO
DROP TABLE IF EXISTS [dbo].[TestTableIgnoredDups]
CREATE TABLE [dbo].[TestTableIgnoredDups](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL
)
ON [PRIMARY]
GO
--create INSTEAD OF trigger
CREATE TRIGGER TestTable_InsteadOfInsert ON dbo.TestTable
INSTEAD OF INSERT
AS
BEGIN
--select rows to be inserted into #temp
SELECT *
INTO #temp
FROM inserted
--insert rows to TestTableIgnoredDups where primary key already exists
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--delete the duplicate rows from #temp
DELETE t
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--insert rows to TestTableIgnoredDups where duplicates
--exist on the inserted virtual table, but not necessarily on TestTable
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.id;
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
DELETE t
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.ID
--insert the remaining rows to TestTable
INSERT INTO TestTable
SELECT *
FROM #temp
END
GO
--verify by trying to insert a duplicate row
insert into testtable(id,ExtraInformation) values(1,'RowOne')
insert into testtable(id,ExtraInformation) values(1,'RowOneDup')
select * from TestTable
select * from TestTableIgnoredDups
Data from TestTable
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOne |
Data from TestTableIgnoreDups
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOneDup |
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with aninstead of
trigger.
– Scott Hodgin
4 hours ago
add a comment |
There would be additional overhead, but one option might be to create an instead of insert
trigger which would check for duplicates first and route those to another table.
--demo setup
set nocount on
DROP TABLE IF EXISTS [dbo].[TestTable]
CREATE TABLE [dbo].[TestTable](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL,
CONSTRAINT [PK_Employee_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
) with (IGNORE_DUP_KEY = ON)
) ON [PRIMARY]
GO
DROP TABLE IF EXISTS [dbo].[TestTableIgnoredDups]
CREATE TABLE [dbo].[TestTableIgnoredDups](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL
)
ON [PRIMARY]
GO
--create INSTEAD OF trigger
CREATE TRIGGER TestTable_InsteadOfInsert ON dbo.TestTable
INSTEAD OF INSERT
AS
BEGIN
--select rows to be inserted into #temp
SELECT *
INTO #temp
FROM inserted
--insert rows to TestTableIgnoredDups where primary key already exists
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--delete the duplicate rows from #temp
DELETE t
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--insert rows to TestTableIgnoredDups where duplicates
--exist on the inserted virtual table, but not necessarily on TestTable
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.id;
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
DELETE t
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.ID
--insert the remaining rows to TestTable
INSERT INTO TestTable
SELECT *
FROM #temp
END
GO
--verify by trying to insert a duplicate row
insert into testtable(id,ExtraInformation) values(1,'RowOne')
insert into testtable(id,ExtraInformation) values(1,'RowOneDup')
select * from TestTable
select * from TestTableIgnoredDups
Data from TestTable
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOne |
Data from TestTableIgnoreDups
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOneDup |
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with aninstead of
trigger.
– Scott Hodgin
4 hours ago
add a comment |
There would be additional overhead, but one option might be to create an instead of insert
trigger which would check for duplicates first and route those to another table.
--demo setup
set nocount on
DROP TABLE IF EXISTS [dbo].[TestTable]
CREATE TABLE [dbo].[TestTable](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL,
CONSTRAINT [PK_Employee_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
) with (IGNORE_DUP_KEY = ON)
) ON [PRIMARY]
GO
DROP TABLE IF EXISTS [dbo].[TestTableIgnoredDups]
CREATE TABLE [dbo].[TestTableIgnoredDups](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL
)
ON [PRIMARY]
GO
--create INSTEAD OF trigger
CREATE TRIGGER TestTable_InsteadOfInsert ON dbo.TestTable
INSTEAD OF INSERT
AS
BEGIN
--select rows to be inserted into #temp
SELECT *
INTO #temp
FROM inserted
--insert rows to TestTableIgnoredDups where primary key already exists
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--delete the duplicate rows from #temp
DELETE t
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--insert rows to TestTableIgnoredDups where duplicates
--exist on the inserted virtual table, but not necessarily on TestTable
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.id;
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
DELETE t
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.ID
--insert the remaining rows to TestTable
INSERT INTO TestTable
SELECT *
FROM #temp
END
GO
--verify by trying to insert a duplicate row
insert into testtable(id,ExtraInformation) values(1,'RowOne')
insert into testtable(id,ExtraInformation) values(1,'RowOneDup')
select * from TestTable
select * from TestTableIgnoredDups
Data from TestTable
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOne |
Data from TestTableIgnoreDups
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOneDup |
There would be additional overhead, but one option might be to create an instead of insert
trigger which would check for duplicates first and route those to another table.
--demo setup
set nocount on
DROP TABLE IF EXISTS [dbo].[TestTable]
CREATE TABLE [dbo].[TestTable](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL,
CONSTRAINT [PK_Employee_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
) with (IGNORE_DUP_KEY = ON)
) ON [PRIMARY]
GO
DROP TABLE IF EXISTS [dbo].[TestTableIgnoredDups]
CREATE TABLE [dbo].[TestTableIgnoredDups](
[ID] [int] NOT NULL,
[ExtraInformation] [varchar](50) NOT NULL
)
ON [PRIMARY]
GO
--create INSTEAD OF trigger
CREATE TRIGGER TestTable_InsteadOfInsert ON dbo.TestTable
INSTEAD OF INSERT
AS
BEGIN
--select rows to be inserted into #temp
SELECT *
INTO #temp
FROM inserted
--insert rows to TestTableIgnoredDups where primary key already exists
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--delete the duplicate rows from #temp
DELETE t
FROM #temp t
JOIN TestTable tt
ON tt.id = t.id
--insert rows to TestTableIgnoredDups where duplicates
--exist on the inserted virtual table, but not necessarily on TestTable
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
INSERT INTO TestTableIgnoredDups
SELECT t.*
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.id;
;WITH DupsOnInserted
AS (
SELECT id
,count(*) AS cnt
FROM #temp
GROUP BY id
HAVING count(*) > 1
)
DELETE t
FROM #temp t
JOIN DupsOnInserted doi
ON doi.id = t.ID
--insert the remaining rows to TestTable
INSERT INTO TestTable
SELECT *
FROM #temp
END
GO
--verify by trying to insert a duplicate row
insert into testtable(id,ExtraInformation) values(1,'RowOne')
insert into testtable(id,ExtraInformation) values(1,'RowOneDup')
select * from TestTable
select * from TestTableIgnoredDups
Data from TestTable
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOne |
Data from TestTableIgnoreDups
| ID | ExtraInformation |
|----|------------------|
| 1 | RowOneDup |
edited 5 hours ago
answered 6 hours ago
Scott HodginScott Hodgin
17k21534
17k21534
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with aninstead of
trigger.
– Scott Hodgin
4 hours ago
add a comment |
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with aninstead of
trigger.
– Scott Hodgin
4 hours ago
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
Can we use any system table to get the info? Because trigger will make server slow if we have large number of rows to be inserted.
– V T Vishwanath
6 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with an
instead of
trigger.– Scott Hodgin
4 hours ago
@VTVishwanath - the only way I know to satisfy your requirement of (Now how to store the record which is failed while insertion because of duplicate primary key.) is with an
instead of
trigger.– Scott Hodgin
4 hours ago
add a comment |
V T Vishwanath is a new contributor. Be nice, and check out our Code of Conduct.
V T Vishwanath is a new contributor. Be nice, and check out our Code of Conduct.
V T Vishwanath is a new contributor. Be nice, and check out our Code of Conduct.
V T Vishwanath is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f227267%2fhow-to-get-the-ignored-row-while-ignore-dup-key-is-on-on-sql-server%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown