Creating Primary Keys - sql-server

I would like to know which column should I put in the PK first, [ID_CHECK] or [ID_CONTROL].
CREATE TABLE QUALITY_CONTROL
(
[ID_CHECK] [int] NULL,
[ID_CONTROL] [int] NOT NULL
)
ALTER TABLE QUALITY_CONTROL ADD CONSTRAINT QUALITY_CONTROL_P01 PRIMARY KEY ([ID_CHECK], [ID_CONTROL])
or
ALTER TABLE QUALITY_CONTROL
ADD CONSTRAINT QUALITY_CONTROL_P01 PRIMARY KEY ([ID_CONTROL], [ID_CHECK])
The [ID_CHECK] column has more repeated data, I don't know if that means anything.
Thanks.

Related

SQL Server foreign key with several cascading paths

I have three tables in SQL Server 2014.
First one is a Product table (productid, ...)
Second one contains ProductVersions of that product (ProductVersionID, ProductID, ...)
Third one contains licenses for the products (LicenseID, ProductID)
These tables have foreign keys on the product ID with on delete cascade.
Now I want to add another table mapping the licenses to specific ProductVersions. This can be a n:m relationship, so I create an mapping table LicenseVersion (LicenseID, ProductVersionID)
When I try to add an foreign key to that relations I get an error saying can't add foreign key because there are loops or serveral cascading paths. Use on delete no action or change the foreign key.
I think, I get why this happens (deleting the product will cause the LicenseVersion row to be deleted from both ways in one transaction) but what is the best practice to solve this?
The database should be consistent anytime, so I don't want to solve this in the software application logic.
I could use a trigger (I think) and an foreign key with no action, but is this the best way?
CREATE TABLE [dbo].[Products]
(
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductName] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_dbo.Products]
PRIMARY KEY CLUSTERED([ProductID] ASC)
)
CREATE TABLE [dbo].[ProductVersions]
(
[ProductVersionID] [int] IDENTITY(1,1) NOT NULL,
[ProductID] [int] NOT NULL,
[Name] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_dbo.ProductVersions]
PRIMARY KEY CLUSTERED ([ProductVersionID] ASC)
)
CREATE TABLE [dbo].[License]
(
[LicenseId] [int] IDENTITY(1,1) NOT NULL,
[LicenseName] [nvarchar](255) NOT NULL,
[ProductId] [int] NOT NULL,
CONSTRAINT [PK_dbo.License]
PRIMARY KEY CLUSTERED ([LicenseId] ASC)
)
CREATE NONCLUSTERED INDEX [IX_ProductId]
ON [dbo].[License] ([ProductId] ASC)
CREATE NONCLUSTERED INDEX [IX_ProductID]
ON [dbo].[ProductVersions] ([ProductID] ASC)
ALTER TABLE [dbo].[License] WITH CHECK
ADD CONSTRAINT [FK_dbo.License_dbo.Products_ProductId]
FOREIGN KEY([ProductId]) REFERENCES [dbo].[Products] ([ProductID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[License] CHECK CONSTRAINT [FK_dbo.License_dbo.Products_ProductId]
ALTER TABLE [dbo].[ProductVersions] WITH CHECK
ADD CONSTRAINT [FK_dbo.ProductVersions_dbo.Products_ProductID]
FOREIGN KEY([ProductID]) REFERENCES [dbo].[Products] ([ProductID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[ProductVersions] CHECK CONSTRAINT [FK_dbo.ProductVersions_dbo.Products_ProductID]
--add new table
CREATE TABLE [dbo].[LicenseVersion]
(
[LicenseID] [int] NOT NULL,
[ProductVersionID] [int] NOT NULL,
CONSTRAINT [PK_LicenseVersion]
PRIMARY KEY CLUSTERED ([LicenseID] ASC, [ProductVersionID] ASC)
)
ALTER TABLE [dbo].[LicenseVersion] WITH CHECK
ADD CONSTRAINT [FK_LicenseVersion_ProductVersions]
FOREIGN KEY([ProductVersionID]) REFERENCES [dbo].[ProductVersions] ([ProductVersionID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[LicenseVersion] CHECK CONSTRAINT [FK_LicenseVersion_ProductVersions]
--error here:
ALTER TABLE [dbo].[LicenseVersion] WITH CHECK
ADD CONSTRAINT [FK_LicenseVersion_Licenses]
FOREIGN KEY([LicenseID]) REFERENCES [dbo].[License] ([LicenseID])
ON UPDATE CASCADE
ON DELETE CASCADE
ALTER TABLE [dbo].[LicenseVersion] CHECK CONSTRAINT [FK_LicenseVersion_Licenses]

Can SQL Server table have a foreign key to a table that resolves to many records?

Consider the following table...
CREATE TABLE [dbo].[Alerts]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[I18NMessageKey] [uniqueidentifier] NOT NULL
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
GO
and the following table...
CREATE TABLE [dbo].[I18NMessages]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Key] [uniqueidentifier] NOT NULL,
[Culture] [nvarchar](200) NOT NULL,
[Message] [nvarchar](max) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
GO
I would like to add a foreign key constraint to table [Alerts] on the column [I18NMessageKey] to refer to many records in table [I18NMessages].
Is this possible without a third table?
The [I18NMessages] table holds the same message for the [Key] but in different languages depending on [Culture]. The relationship between [Alerts] and [I18NMessages] doesn't care about the culture. The resolution of [Culture] depends on the user at runtime.
In SQL Server, the uniqueness of the referenced key column(s) must be enforced by a primary key, unique constraint, or unique index. You need a third table with a unique I18NMessageKey column key to enforce referential integrity.
You can create a trigger and implement custom business logic

SQL Relation MORE on MORE

I have a question about this relation betweed SpelerTeam and Toernooi, i get a error, can someone help me with it all the other relations do work:
Msg 1776, Level 16, State 0, Line 2 There are no primary or candidate
keys in the referenced table 'SpelerTeam' that match the referencing
column list in the foreign key 'FK__Toernooi__team__1A14E395'. Msg
1750, Level 16, State 0, Line 2 Could not create constraint. See
previous errors.
CREATE TABLE dbo.LoginGegevens
(
Username varchar(25) NOT NULL,
Wachtwoord varchar(25) NOT NULL,
LoginDatum date NOT NULL,
)
CREATE TABLE dbo.NawGegevensKind
(
KindSpeler varchar(25) NOT NULL,
NawKind varchar(50) NOT NULL,
)
CREATE TABLE dbo.NawGegevensProfspeler
(
Profspeler varchar(25) NOT NULL,
NawProfspeler varchar(50) NOT NULL,
)
CREATE TABLE dbo.SpelerTeam
(
Team int NOT NULL,
Kindspeler varchar(25) NOT NULL,
Profspeler varchar(25) NOT NULL,
)
CREATE TABLE dbo.Toernooi
(
team int NOT NULL,
score int NOT NULL,
games int NOT NULL,
rondes int NOT NULL,
)
-- primary keys
ALTER TABLE LoginGegevens
ADD primary KEY (Username)
ALTER TABLE NawGegevensKind
ADD primary KEY (KindSpeler)
ALTER TABLE NawGegevensProfspeler
ADD primary KEY (ProfSpeler)
ALTER TABLE SpelerTeam
ADD primary KEY (Team,KindSpeler,ProfSpeler)
ALTER TABLE Toernooi
ADD primary KEY (Team,Rondes,Games)
-- relation
ALTER TABLE SpelerTeam
ADD FOREIGN KEY (Kindspeler)
REFERENCES NawGegevensKind(Kindspeler);
ALTER TABLE SpelerTeam
ADD FOREIGN KEY (Profspeler)
REFERENCES NawGegevensProfspeler(Profspeler);
ALTER TABLE Toernooi
ADD FOREIGN KEY (Team)
REFERENCES SpelerTeam(Team);
The Primary Key of SpelerTeam is Team,KindSpeler,ProfSpeler.
That means that any foreign key that references that table has to reference all three of those columns. You can't create a foreign key that uses only team.
You need an index on a colum so that it can be referenced as a foreign key efficiently. Add an index on SpelerTeam.Team and on all other columns with the same problem. Try CREATE INDEX IX_SpelerTeam_Team_Team ON SpelerTeam (Team);
Add below after all tables have been created:
CREATE UNIQUE NONCLUSTERED INDEX IX_SpelerTeam_Team
ON dbo.SpelerTeam (Team);
GO
As it was pointed in another answer you cannot reference to non unique column, to make column unique you can make this column primary key or create index for this column.
It is not enough that your "Team" column is part of composite key.

relationship many to many

I want to create database with relationship many to many. But i have error
SQL71516 :: The referenced table '[dbo].[BookAuthors]' contains no
primary or candidate keys that match the referencing column list in
the foreign key. If the referenced column is a computed column, it
should be persisted. SQL71516 :: The referenced table
'[dbo].[BookAuthors]' contains no primary or candidate keys that match
the referencing column list in the foreign key. If the referenced
column is a computed column, it should be persisted.
How to fix this?
CREATE TABLE [dbo].[BookAuthors] (
[Book] INT NOT NULL,
[Author] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Book] ASC,[Author] ASC)
);
CREATE TABLE [dbo].[Books] (
[Id] INT NOT NULL,
[Title] NVARCHAR (MAX) NULL,
[Price] MONEY NULL,
[Category] INT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
FOREIGN KEY ([Id]) REFERENCES [dbo].[BookAuthors] ([Book])
);
CREATE TABLE [dbo].[Authors] (
[Id] INT NOT NULL,
[Name] NCHAR (10) NOT NULL,
PRIMARY KEY CLUSTERED ([Id]),
FOREIGN KEY ([Id]) REFERENCES [dbo].[BookAuthors] ([Author])
);
You crated in you BookAuthors composite primary key which consists of two columns: Book and Author. When referencing it, you need to reference both columns.
Other solution is to make in BookAuthors third column (identity maybe) which would be primary key and reference that one.
The Following Image Shows you the Table Structure.

Dropping PRIMARY KEY constraint

I have created a table which has two columns combined as a primary key.
CREATE TABLE [dbo].[Workflow_Name]
(
[Workflow_ID] [int] NOT NULL,
[Unique_Workflow_ID] [int] NOT NULL,
[Workflow_Name] [varchar](255) NULL,
[Row_ID] [int] NULL,
[ReleaseVersion] [varchar](255) NULL,
[Release] [varchar](255) NULL,
CONSTRAINT [PK_WorkFlowName] PRIMARY KEY CLUSTERED
([Workflow_ID] ASC, [Unique_Workflow_ID] ASC )
)
As seen , [Workflow_ID] ASC, [Unique_Workflow_ID] ASC combined together are forming the Primary key.
Now i want to remove [Unique_Workflow_ID] from the Primary key constraint and maintain only [Workflow_ID] as Primary Key.
How to do it?
You can do it by executing the following statements in SSMS Query Window after selecting the database that the table is in.
ALTER TABLE [dbo].[Workflow_Name]
DROP CONSTRAINT [PK_WorkFlowName]
ALTER TABLE [dbo].[Workflow_Name]
ADD CONSTRAINT [PK_WorkFlowName] PRIMARY KEY ([Workflow_ID] ASC)
Please note, in order for it to work, if you have existing rows in the [Workflow_Name], then the data in this new single column Primary Key i.e. in [Workflow_ID] must be unique per row. Otherwise the ALTER statement will (rightly) throw an error that data is not unique in that column.
You can remove your primary key constraint and then create a new one only with the Workflow_ID. But make sure it has only unique values.

Resources