IGNORE_DUP_KEY in Sql Server 2000 with composite primary key - sql

I'm trying to create a table in SQL Server 2000, that has a composite primary key with IGNORE_DUP_KEY set to ON.
I've tried looking for this option in SQL Server Management Studio Express but I couldn't find it so now I'm down to creating the table programatically. Every SQL command I found on Google or Stack Overflow gives me an error:
Incorrect syntax near '('.
The table should have 4 columns (A,B,C,D) all decimal(18) and I need the primary key on A,B,C.
I would appreciate if someone could post an example CREATE command.

create table MyTable2 (
[a] decimal(18,2) not null,
[b] decimal(18,2) not null,
[c] decimal(18,2) not null,
[d] decimal(18,2),
CONSTRAINT myPK PRIMARY KEY (a,b,c)
)
CREATE UNIQUE INDEX MyUniqueIgnoringDups
ON MyTable2 (a,b,c)
WITH IGNORE_DUP_KEY --SQL 2000 syntax
--WITH(IGNORE_DUP_KEY = On) --SQL 2005+ syntax
--insert some data to test.
insert into mytable2 (a,b,c,d) values (1,2,3,4);--succeeds; inserts properly
insert into mytable2 (a,b,c,d) values (1,2,3,5);--insert fails, no err is raised.
-- "Duplicate key was ignored. (0 row(s) affected)"
For anyone interested, here's an explanation of what's happening from Erland Sommarskog on the MSDN forums:
When IGNORE_DUP_KEY is OFF, a duplicate key value causes an error and the entire statement is rolled back. That is, if the statement attempted to insert multiple rows, no rows are inserted.
When IGNORE_DUP_KEY is ON, a duplicate key value is simply ignored. The statement completes successfully and any other rows are inserted.

Related

Why does insert into table with primary key/identity column generate "Column name or number of supplied values does not match table definition" error

Table has a primary key/identity column with seed/increment of 1/1. When I try to insert a record into the table while omitting the primary key column because SQL should automatically assign that column a value, I get the following error: "Column name or number of supplied values does not match table definition."
I tried inserting a record while omitting the primary key/identity field.
I tried inserting a record with an explicit primary key/identity value and received the following error: "The user did not have permission to write to the column."
I tried setting IDENTITY_INSERT to ON and received the following error: "Cannot find the object "dbo.temp" because it does not exist or you do not have permissions."
CREATE TABLE [dbo].[temp](
[ProjectNumber] [INT] IDENTITY(1,1) NOT NULL,
[ServiceCenterID] [INT] NULL,
CONSTRAINT [PK_temp] PRIMARY KEY CLUSTERED
(
[ProjectNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY]
INSERT dbo.temp
SELECT 1 [ServiceCenterID]
I expect a record to be inserted into the table with the primary key/identity column (projectNumber) automatically assigned a value of 1. Instead I get the error "Column name or number of supplied values does not match table definition." even though projectNumber is a IDENTITY column
If you want to assign the ProjectNumber, then you need to bring in two columns.
INSERT dbo.temp (ProjectNumber, ServiceCenterID)
SELECT 1, 1 as [ServiceCenterID];
If you want it set automatically, then:
INSERT dbo.temp (ServiceCenterID)
SELECT 1;
The key idea in both cases is to list the columns explicitly. That way, you are less likely to make errors on INSERTs. And, if you do, they should be easier to debug.

SQL type IGNORE_DUP_KEY

CREATE TYPE [dbo].[IdList] AS TABLE ([Id] [int] NULL)
GO
How can I insert the same value multiple times in a type?
Guess it is something like IGNORE_DUP_KEY, but I can't seem to get to work
If there is no key or index on the column (as there isn't, in the statement you've given) then there already is no restriction on inserting the same value multiple times in a table.
DECLARE #i IdList
INSERT #i VALUES (1), (1), (1)
will work just fine. If you want to have a unique index with the IGNORE_DUP_KEY option so inserts will be discarded if the value is already there, rather than producing a constraint violation, you can do so by including a unique index with that option in the declaration:
CREATE TYPE [dbo].[IdList] AS TABLE (
[Id] [int] NULL,
INDEX IX_IdList_Id UNIQUE(ID) WITH (IGNORE_DUP_KEY = ON)
);
Or with a primary key (for non-nullable columns):
CREATE TYPE [dbo].[IdList] AS TABLE ([Id] [int] PRIMARY KEY WITH (IGNORE_DUP_KEY = ON));
Be careful with this, because silently discarding duplicate values can be a real good way to mask essential problems in your processing. SQL Server does produce the informational message "Duplicate key was ignored", but that message is itself easy to ignore (and gives no details on what key(s)).
Jeroen Mostert did tell me just to remove the key and i did ant did work

SQL Insert Failing - Violation of Primary Key Constraint

I am seeing a very strange issue with a SQL Insert statement, I have a simple table, with an ID and 2 datetimes, see create script below -
CREATE TABLE [dbo].[DATA_POPULATION_LOGS](
[ID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[START] [datetime] NOT NULL,
[FINISH] [datetime] NOT NULL,
CONSTRAINT [PK__DATA_POP__3214EC2705D8E0BE] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I am now trying to run the following insert script -
INSERT INTO [dbo].[DATA_POPULATION_LOGS]
([START]
,[FINISH])
VALUES
(GETDATE()
,GETDATE())
It is failing with the following error -
Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK__DATA_POP__3214EC2705D8E0BE'. Cannot insert duplicate key in object 'dbo.DATA_POPULATION_LOGS'. The duplicate key value is (11).
The duplicate key value in the error message above increases every time the insert is executed, so it seems to know it is an identity column.
What would be causing this issue?!
Thanks in advance.
Simon
EDIT
I have now created a copy of this table and can insert into the new table fine using that script, what could be causing it to fail?
Probably someone issued DBCC CHECKIDENT against the table. When you do this, SQL Server will obey you, and try to generate values starting from the RESEED and incrementing by the increment. It doesn't check first to see if those values already exist (even if there is a PK). Simple repro that generates the same error:
USE tempdb;
GO
CREATE TABLE dbo.floob(ID INT IDENTITY(1,1) PRIMARY KEY);
GO
INSERT dbo.floob DEFAULT VALUES;
GO
DBCC CHECKIDENT('dbo.floob', RESEED, 0);
GO
INSERT dbo.floob DEFAULT VALUES;
GO
DROP TABLE dbo.floob;
To stop this from happening, you could figure out what the max value is now, and then run CHECKIDENT again:
DBCC CHECKIDENT('dbo.tablename', RESEED, <max value + 10 or 20 or something here>);

How can I avoid failing an entire INSERT batch due to 1 NULL

I have a table with a primary key and a stored procedure I use to insert to that table. I have no control over the stored procedure and cannot change it. Sometimes the procedure returns many records and 1 record with a NULL value for the primary key column. At the moment, the entire batch of new rows fails to insert.
How can I configure my code or the table to fail only on the 1 row with the NULL value, but allow the other rows to be inserted?
Here is some test code:
IF OBJECT_ID('tempdb..#tbl') IS NOT NULL
DROP TABLE #tbl
CREATE TABLE #tbl (
col INT NOT NULL,
CONSTRAINT PK_tbl PRIMARY KEY (col ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
SET XACT_ABORT OFF
--Imagine this is the procedure that cannot be edited
insert into #tbl (col) values
(null), (1), (2)
--Ideally, the table would have 1 and 2
select * from #tbl
Assuming we're not really talking about a #temporary table, you could create an instead of insert trigger.
CREATE TRIGGER dbo.PreventNullsOnTableName
ON dbo.TableName
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TableName SELECT col1 FROM inserted WHERE col1 IS NOT NULL;
END
GO
You may also want to use GROUP BY col1 to prevent PK violations, but that depends on whether you want to handle that gracefully or raise an error.
You could also remove the NOT NULL constraint and instead of having a PRIMARY KEY, create a unique filtered index WHERE col1 IS NOT NULL.
Don't have NOT NULL on col INT. It can still be PK but it will only allow one null. Then you can delete the null row.
OK I was wrong the PK cannot be null. But you can have a null unique non clustered index. It is fundamentally a PK but not clustered. If the insert has at most one null then the insert will succeed and you can then delete the 1 row that is null.

How can I change primary key on SQL Azure

I am going to change the primary key on SQL Azure. But it throws an error when using Microsoft SQL Server Management Studio to generate the scripts. Because every tables on SQL Azure must contains a primary key. And I can't drop it before create. What can I do if I must change it?
Script generated
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[mytable]') AND name = N'PK_mytable')
ALTER TABLE [dbo].[mytable] DROP CONSTRAINT [PK_mytable]
GO
ALTER TABLE [dbo].[mytable] ADD CONSTRAINT [PK_mytable] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF)
GO
Error message
Msg 40054, Level 16, State 2, Line 3
Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again.
Msg 3727, Level 16, State 0, Line 3
Could not drop constraint. See previous errors.
The statement has been terminated.
Msg 1779, Level 16, State 0, Line 3
Table 't_event_admin' already has a primary key defined on it.
Msg 1750, Level 16, State 0, Line 3
Could not create constraint. See previous errors.
I ran into this exact problem and contacted the Azure team on the forums. Basically it isn't possible. You'll need to create a new table and transfer the data to it.
What I did was create a transaction and within it do the following:
Renamed the old table to OLD_MyTable.
Create the new table with the correct Primary Key and call it MyTable.
Select the contents from OLD_MyTable
into MyTable.
Drop OLD_MyTable.
You may also need to call sp_rename on any constraints so they don't conflict.
See also: http://social.msdn.microsoft.com/Forums/en/ssdsgetstarted/thread/5cc4b302-fa42-4c62-956a-bbf79dbbd040
upgrade SQL V12 and heaps are supported on it. So you can drop the primary key and recreate it.
I appreciate that this may be late in the day for yourself, but it may help others.
I recently came across this issue and found the least painful solution was to download the database from Azure, restore it locally, update the primary key locally (as the key constraint is a SQL Azure specific issue), and then restore the database back into Azure.
This saved any issues in regards to renaming databases or transferring data between them.
You can try the following scripts. Change it to suit for your table def.
EXECUTE sp_rename N'[PK_MyTable]', N'[PK_MyTable_old]', 'OBJECT'
CREATE TABLE [dbo].[Temp_MyTable](
[id] [int] NOT NULL,
[text] [text] NOT NULL CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED (
[id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON))
INSERT INTO dbo.[Temp_MyTable] (Id, Text)
SELECT Id, Text FROM dbo.MyTable
drop table dbo.MyTable
EXECUTE sp_rename N'Temp_MyTable', N'MyTable', 'OBJECT'
This question is outdated because changing PK is already supported in latest version of SQL Azure. And you don't have to create temporary table.