Add non-null unique constraint - not index - sql-server

Basically I want to turn this:
ALTER TABLE [dbo].[Computer] ADD CONSTRAINT [AK_ResourceId] UNIQUE NONCLUSTERED
(
[ResourceId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Into not affecting NULL values. The other posts only give an answer to make a unique index, but an index does not create violation when a duplicate value occurs on INSERT. I want a constraint, but I can't seem to make a WHERE statement on this..
Using SQL Server 2014
Update
It does work with an index after all :)
SQL:
CREATE UNIQUE NONCLUSTERED INDEX IX_ResourceId
ON dbo.Computer(ResourceId)
WHERE ResourceId IS NOT NULL;
This will create the following error:
Cannot insert duplicate key row in object 'dbo.Computer' with unique index 'IX_ResourceId'. The duplicate key value is (1234)

Related

Unique constraint on multiple columns when any columns are not null

I am trying to add a unique constraint on 2 columns that allows multiple (null, null), but doesn't allow multiple ("a", null). I wrote the following SQL statement but I get an error
Incorrect syntax near the keyword 'with'
SQL statement:
CREATE UNIQUE NONCLUSTERED INDEX [UQ]
ON [dbo].[MyTable] ([Column_A], [Column_B])
WHERE [Column_A] IS NOT NULL OR [Column_B] IS NOT NULL
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY];
However in
WHERE [Column_A] IS NOT NULL OR [Column_B] IS NOT NULL
when I replace OR with AND, there is no syntax error anymore. But what I want is OR logic, not AND because using AND allows multiple ("a", null) entries.
So why is there an incorrect syntax error using OR? Thanks.
It's a bit clunky, but if the point is to enforce uniqueness (except for NULL/NULL) and you're happy having two indexes, you can do it via putting the NOT NULL filters on separate indexes e.g.,
CREATE UNIQUE NONCLUSTERED INDEX
[UQ_A] ON [dbo].[MyTable]
(
[Column_A],
[Column_B]
)
WHERE [Column_A] IS NOT NULL
GO
CREATE UNIQUE NONCLUSTERED INDEX
[UQ_B] ON [dbo].[MyTable]
(
[Column_A],
[Column_B]
)
WHERE [Column_B] IS NOT NULL
GO
While it's not necessary for the uniqueness check, you may want to change the order of the fields in the second index to potentially gain additional advantages of the index (depending on how these fields are used in your application - it may be better swapping them in the first index), e.g.,
CREATE UNIQUE NONCLUSTERED INDEX
[UQ_B] ON [dbo].[MyTable]
(
[Column_B],
[Column_A]
)
WHERE [Column_B] IS NOT NULL
GO
According to Martin Smith's comment, I think I can implement it by:
CREATE VIEW [dbo].[TableAView]
WITH SCHEMABINDING AS
SELECT
[ColumnA] = [ColumnA],
[ColumnB] = [ColumnB]
FROM [dbo].[TableA]
WHERE [ColumnA] IS NOT NULL OR [ColumnB] IS NOT NULL;
GO
CREATE UNIQUE CLUSTERED INDEX
[UQ] ON [dbo].[TableAView]
(
[ColumnA],
[ColumnB]
)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY];
GO

SQL Server unique constraint failing to discard duplicate record

I am adding a constraint on multiple column in one the table of my SQL Server database.
Below is the query to add the constraint:
ALTER TABLE [db].[tablename]
ADD CONSTRAINT [contact_uniq_constraint]
UNIQUE NONCLUSTERED ([account_id_fk] ASC, [contact_type] ASC,
[contact] ASC, [country_code] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,
ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
But I am still able to add duplicate in the table. Can someone help me identify the reason?

Composite key in where condition - SQL Server

I'm involved in some data cleaning activities. My table does not have any unique identifier. So I decided to take 3 columns and make the index like below:
ALTER TABLE [dbo].[ISFTX]
ADD CONSTRAINT ISFTX_UNQ UNIQUE (IDNO,ACCTNUM,PANNO)
After altering table, a part of my alter script looks like this:
CONSTRAINT [ISFTX_UNQ] UNIQUE NONCLUSTERED
(
[IDNO] ASC,
[ACCTNUM] ASC,
[PANNO] 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 want to use the combination of 3 columns as ONE KEY and put it in where condition so that I can search for other column values in the same table using this where condition(ONE KEY). How can I do this?
I would prefer any example of "Where" condition and this will help? OR Please suggest me any better way of doing this? Thanks.

Clustered primary key and relations

I'm struggeling with the primary keys in my database:
As you can see I use a clustered index. When I try to insert something like:
I get exception that the primary key is duplicated, that is not what I expected. The combination of idQuestionaire and version needs to be unique so that my insert script will work.
I tried the following:
In the "Keys" folder of servey there are 4 keys(the primary, the foreign key from parkinglottype, survey$idQuestionnaire_UNIQUE and survey$version_UNIQUE)
After removing the UNIQUE keys the insert script works fine but my foreign key to surveyquestion does not work anymore...
This is the code of "survey$idQuestionnaire_UNIQUE":
ALTER TABLE [dbo].[survey] ADD CONSTRAINT [survey$idQuestionnaire_UNIQUE] UNIQUE NONCLUSTERED
(
[idQuestionnaire] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
And here my primary key:
ALTER TABLE [dbo].[survey] ADD CONSTRAINT [PK_survey_idQuestionnaire] PRIMARY KEY CLUSTERED
(
[idQuestionnaire] ASC,
[version] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
How can I make the clustered Primary Key unique with 2 column and still be able to use it as a foreign key?
If the primary key of "survey" is the two columns "idQuestionnaire" and "version", then adding a unique index to "idQuestionnaire" is a mistake. That column alone is not unique, as is obvious from both your primary key constraint and your INSERT statement.
SQL Server builds an index on the primary key. Additional indexes on primary key columns are usually not necessary.
Your foreign key constraint needs to reference the pair of columns, as ...(Survey_idQuestionnaire, Survey_version) references [dbo].[survey] (idQuestionnaire, version).

Filtered non-clustered Index abnormal behaivior

I have a table that created some filtered non-clustered on some columns such:
CREATE UNIQUE NONCLUSTERED INDEX [IX_Sh_Esh] ON [dbo].[My_Tbl]
(
[City_Code] ASC,
[Sh_Esh] ASC
)
WHERE ([Sh_Bod]=(0) AND [Noe_Fa]=(0))
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
and:
CREATE UNIQUE NONCLUSTERED INDEX [IX_Kho] ON [dbo].[My_Tbl]
(
[City_Code] ASC,
[Kho] ASC
)
WHERE ([Sh_Bod]=(0) AND [Sh_Esh]=(0) AND [Noe_Fa]=(1))
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
I create this indexes on my table with no error but when I want to add a new column I get this error:
'My_Tbl' table
- Unable to create index 'IX_Sh_Esh'.
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'My_Tbl' and the index name 'IX_Sh_Esh'. The duplicate key value is (3, 0).
The statement has been terminated.
my table data is:
According to first Index because the rows No. 1 and No. 4 does not satisfy the where cluase should not create index on them.Why I get the above error?
thanks
EDIT 1) :
there is Interesting point.If I delete that index and add the Column(s) then ReCreate that Index,the index create with no error.STRANGE!!!!
The reason you can drop the index and then add the data, then recreate the index is because creating an index does not check existing data, just data that you are trying to insert/update.
You're not getting the error because its a filtered index, you're getting it because its a unique index and you're trying to add duplicate values to the table's column that the unique index is on. That's the beaty of them! If you need duplicate data don't make the index unique.

Resources