Clustered primary key and relations - sql-server

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).

Related

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?

Add non-null unique constraint - not index

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)

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.

primary key name is required field?

Is there any difference between the below 2 CREATE TABLE statements in SQL Server 200x/2012? I generated this script from two different tables, one had a Key name defined (PK_Table1) whereas the other had some kind of randomly generated number associated to it (PK_Table1_1084F446).
CREATE TABLE [dbo].[Table1](
[ID] [uniqueidentifier] NOT NULL,
<<Other Column declaration here>>
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]
GO
Few more non-clustered indexes declaration here
CREATE TABLE [dbo].[Table1](
[ID] [uniqueidentifier] NOT NULL,
<<Other Column declaration here>>
CONSTRAINT [PK_Table1] 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]
GO
Few more non-clustered indexes declaration here
It works in the same way, but natural names are more convenient:
1) when altering constraint you can easy refer to it (if you gave sensible name);
2) when query failed due to constraint, name of this constraint is showed, so you can easily know what cause an error (if you gave sensible name).

Is a primary key automatically an index?

If I run Profiler, then it suggests a lot of indexes like this one
CREATE CLUSTERED INDEX [_dta_index_Users_c_9_292912115__K1] ON [dbo].[Users]
(
[UserId] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF,
ONLINE = OFF) ON [PRIMARY]
UserId is the primary key of the table Users. Is this index better than the one already in the table:
ALTER TABLE [dbo].[Users] ADD CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED
(
[UserId] 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]
Yes a primary key is always an index.
If you don't have any other clustered index on the table, then it's easy: a clustered index makes a table faster, for every operation. YES! It does. See Kim Tripp's excellent The Clustered Index Debate continues for background info.
So really, every useful table (except for maybe staging tables for bulkload or another few rare cases) ought to have a clustered index. If you don't have one, it's quite obvious the DTA would recommend one, and put it on the Primary Key column(s) by default.
Every table needs a clustered index and a primary key. By default, the PK is clustered but it can be non-clustered if you want like you're done.
You have specified a non-clustered PK so the profiler suggests a clustered index...
Note: a table without a clustered index is called a "heap" because it's a pile of unstructured data...
It is essentially suggesting that you should make the primary key a clustered index rather than an unclustered one. In most cases, this would be a good thing to do.
It is better because it is clustered.

Resources