Adding Composite Foreign Key - sql

I am having a problem adding a foreign key constraint to SQL 2008 that is based on a composite primary key in another table. I have followed some directions based on a few posts on here, but haven't been able to get it to work.
I have two tables:
CREATE TABLE [Staging].[ActivityLog](
[ActivityLogId] [int] IDENTITY(1,1) NOT NULL,
...
[ActivityLogType] [varchar](10) NOT NULL,
[ActivityLogSubType] [varchar](10) NOT NULL,
CONSTRAINT [PK_ActivityLog] PRIMARY KEY CLUSTERED
(
[ActivityLogId] ASC
))
and
CREATE TABLE [Staging].[ActivityLogTypeSubType](
[ActivityLogType] [varchar](10) NOT NULL,
[ActivityLogSubType] [varchar](10) NOT NULL,
CONSTRAINT [PK_ActivityLogTypeSubType] PRIMARY KEY CLUSTERED
(
[ActivityLogType] ASC,
[ActivityLogSubType] ASC
))
GO
I am trying to add a foreign key like this:
ALTER TABLE Staging.ActivityLog
ADD CONSTRAINT FK_ActivityLog_ActivityLogTypeSubType
FOREIGN KEY(ActivityLogType, ActivityLogSubType)
REFERENCES Staging.ActivityLogTypeSubType(ActivityLogType, ActivityLogSubType)
I get this error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_ActivityLog_ActivityLogTypeSubType". The conflict occurred in database "HMDB_DEV", table "Staging.ActivityLogTypeSubType".
I have verified that this FK doesn't already exist.
I apologize for the lengthy post. Any help would be greatly appreciated.
Thanks,
James

Have you verified data to match FK logic?

Related

How can I define a UNIQUE constraint that applies to multiple columns in a DataSet table?

I have the following table defined in a .sql script file.
CREATE TABLE [HwComponent](
[HwComponentId] [int] NOT NULL,
[HwComponentTypeId] [int] NOT NULL,
[ManufactureId] [int] NOT NULL,
[SerialNumber] [nvarchar](100) NOT NULL,
[AssignmentType] [nvarchar](1000) NOT NULL,
[IsFunctional] [nvarchar](10) NOT NULL,
[Note] [nvarchar](4000) NULL,
CONSTRAINT [PK_HwComponent] PRIMARY KEY ([HwComponentId]),
CONSTRAINT (FK1_HwComponent] FOREIGN KEY ([HwComponentTypeId]) REFERENCES [HwComponentType] ([HwComponentTypeId)] ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT (FK2_HwComponent] FOREIGN KEY ([HwComponentTypeId], [ManufactureId]) REFERENCES [HwComponentTypeManufacturerInfo] ([HwComponentTypeId], [ManufactureId]) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT (UI1_HwComponent] UNIQUE ([HwComponentTypeId], [ManufactureId], [SerialNumber]))
GO
I now need to define a new table in the DataSet Designer to match.
I believe I have everything defined correctly, except the UNIQUE constraint that requires all 3 columns be considered together as the unique constraint.
How do I define the UNIQUE constraint for this table in the DataSet Designer?
SQL CE Service 4.0 SP1:
VS Prof 2017 - Version 15.8.7
Your code should work if properly formatted. You have parens where you shouldn't:
CREATE TABLE [HwComponent](
[HwComponentId] [int] NOT NULL,
[HwComponentTypeId] [int] NOT NULL,
[ManufactureId] [int] NOT NULL,
[SerialNumber] [nvarchar](100) NOT NULL,
[AssignmentType] [nvarchar](1000) NOT NULL,
[IsFunctional] [nvarchar](10) NOT NULL,
[Note] [nvarchar](4000) NULL,
CONSTRAINT PK_HwComponent PRIMARY KEY ([HwComponentId]),
CONSTRAINT FK1_HwComponent FOREIGN KEY ([HwComponentTypeId]) REFERENCES [HwComponentType] ([HwComponentTypeId)] ON DELETE NO ACTION ON UPDATE NO ACTION
CONSTRAINT K2_HwComponent FOREIGN KEY ([HwComponentTypeId], [ManufactureId]) REFERENCES [HwComponentTypeManufacturerInfo] ([HwComponentTypeId], [ManufactureId]) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT UI1_HwComponent UNIQUE ([HwComponentTypeId], [ManufactureId], [SerialNumber])
);
I would advise you to get rid of all the square braces. They just make the code harder to write and to read and to modify.
Does this work for you?
CREATE UNIQUE INDEX ixYourConstraint ON HwComponent (col1, col2);
This similar post might be of help to you:
MsSql Compact, unique constraint on two and more columns
Thanks Algef and Gordon for you responses.
Sorry about the confusion. My bad. :-)
The SQL sample works fine. I used it as an example only. I actually need to represent this table exactly using the DataSet Designer in VS. The table should look something like the following when done.
HwComponent Table in the DataSet Designer
My problem is I'm not having success in defining the UNIQUE group properly in the DataSet Designer.
I need to define a UNIQUE GROUP that consists of the HwComponentTypeId, ManufactureId and SerialNumber columns.
Any ideas?
Thanks again for any help

Creating a foreign key to compound primary key

I have two tables - Educators and Faculties:
CREATE TABLE [dbo].[Educators]
(
[UserId] [nvarchar](128) NOT NULL,
[FacultyId] [smallint] NOT NULL,
[InstitutionUserId] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Educators]
PRIMARY KEY CLUSTERED ([UserId] ASC)
)
CREATE TABLE [dbo].[Faculties]
(
[InstitutionUserId] [nvarchar](128) NOT NULL,
[FacultyId] [smallint] NOT NULL,
CONSTRAINT [PK_UserFaculties]
PRIMARY KEY CLUSTERED ([InstitutionUserId] ASC, [FacultyId] ASC)
)
The table Faculties has a compound primary key made up from two columns (InstitutionUserId and FacultyId). I also have the same column in the Educators table. I want to link those two tables together with a foreign key.
So, this is my query:
ALTER TABLE [dbo].[Educators] WITH CHECK
ADD CONSTRAINT [FK_Educators_FacultyId_Faculties_FacultyId]
FOREIGN KEY ([FacultyId], [InstitutionUserId])
REFERENCES [dbo].[Faculties] ([FacultyId], [InstitutionUserId])
But I getting this error message:
Msg 1776, Level 16, State 0, Line 7
There are no primary or candidate keys in the referenced table 'dbo.Faculties' that match the referencing column list in the foreign key 'FK_Educators_FacultyId_Faculties_FacultyId'.
Msg 1750, Level 16, State 1, Line 7
Could not create constraint or index. See previous errors.
How to solve this problem?
Your tables and their constraints look fine. The only issue I can see is that the order of the columns in your primary key
CONSTRAINT [PK_UserFaculties] PRIMARY KEY CLUSTERED
(
[InstitutionUserId] ASC,
[FacultyId] ASC
)
is different from the order that you've declared in your foreign key constraint
ALTER TABLE [dbo].[Educators] WITH CHECK ADD CONSTRAINT [FK_Educators_FacultyId_Faculties_FacultyId] FOREIGN KEY([FacultyId], [InstitutionUserId])
REFERENCES [dbo].[Faculties] ([FacultyId], [InstitutionUserId])
Try changing the order of the columns in the declaration of your foreign key like this:
ALTER TABLE [dbo].[Educators] WITH CHECK ADD CONSTRAINT [FK_Educators_FacultyId_Faculties_FacultyId] FOREIGN KEY([InstitutionUserId], [FacultyId])
REFERENCES [dbo].[Faculties] ([InstitutionUserId], [FacultyId])
The keys should be in the same order that they are defined:
ALTER TABLE dbo.Educators
ADD CONSTRAINT FK_Educators_FacultyId_Faculties_FacultyId
FOREIGN KEY(InstitutionUserId, FacultyId)
REFERENCES dbo.Faculties(InstitutionUserId, FacultyId);

Primary and foreign keys database design

I am creating SQL Server tables for a currency exchange system.
I have one table which is the following:
CREATE TABLE [CurrencyKeys]
(
[Key] [nchar](3) NOT NULL,
[Currency] [nvarchar](30) NOT NULL
CONSTRAINT [PK_Key] PRIMARY KEY ([Key])
);
How would I create the table for the exchange rates itself which references the keys from the CurrencyKeys table?
Currently I have the following:
CREATE TABLE [ExchangeRates]
(
[DateTime] [datetime]NOT NULL,
[FromCurrCode] [nchar](3) NOT NULL,
[ToCurrCode] [nchar] (3) NOT NULL,
[Rate] [money] NOT NULL
)
Would I need to create (FromCurrCode, ToCurrCode) as primary key as well?
If I understand you correctly, you need to define the foreign keys on the exchangeRates table.
You would define a foreign key for EACH column, like so:
alter table [ExchangeRates] add constraint fk_ExchangeRates_01 foreign key (fromCurrCode) references CurrencyKeys([Key]);
alter table [ExchangeRates] add constraint fk_ExchangeRates_02 foreign key (toCurrCode) references CurrencyKeys([Key]);
That will define foreign keys for your exchangeRates table.
Don't you just want to do this?
CREATE TABLE [ExchangeRates]
(
[DateTime] [datetime]NOT NULL,
[FromCurrCode] [nchar](3) NOT NULL,
[ToCurrCode] [nchar] (3) NOT NULL,
[Rate] [money] NOT NULL,
Foreign Key([FromCurrCode]) References [CurrencyKeys]([Key]),
Foreign Key([ToCurrCode]) References [CurrencyKeys]([Key])
)
Or are you trying to ask how to maintain primary key values for ExchangeRates table itself. Can you please make yourself clear?
It depends on whether your table could have several rows referring to the same (From,To) pair (to track different exchange rates on different dates)
If that is the case, then the PK could be (FromCurrCode, ToCurrCode, DateTime)
If you are only saving one/the last exchange rate, then (FromCurrCode, ToCurrCode) should be enough.
It appears that you are using natural keys in lieu of surrogate keys.
In order for the ExchangeRates table to use natural keys, you would need to create a composite primary key using FromCurrCode and ToCurrCode
CREATE TABLE [ExchangeRates]
(
[DateTime] [datetime]NOT NULL,
[FromCurrCode] [nchar](3) NOT NULL,
[ToCurrCode] [nchar] (3) NOT NULL,
[Rate] [money] NOT NULL
CONSTRAINT [PK_ExchangeRates] PRIMARY KEY ([FromCurrCode], [ToCurrCode])
)

Composite Primary Key + Foreign Key

I have a table which contains a list of Surveys (PK is ID)
CREATE TABLE [dbo].[SurveyMaster](
[ID] [nvarchar](4) NOT NULL,
[Title] [nvarchar](200) NULL,
[IsActive] [bit] NOT NULL,
And a table which contains a list of Variable Mappings.
CREATE TABLE [dbo].[VariableMappings](
[ParentSurvey_ID] [nvarchar](4) NOT NULL,
[ReportingMonth] [nvarchar](6) NOT NULL,
[VariableName] [nvarchar](400) NOT NULL,
[Value] [int] NOT NULL
My hope was to create a primary key for VariableMappings on ParentSurvey_ID, ReportingMonth and Variable Name to ensure a unique record.
At the same time though, I'd like a foreign key relationship between VariableMappings.ParentSurvey_ID and SurveyMaster.ID to ensure VariableMappings only contains relevant SurveyID's.
I've tried a couple of approaches in SQL Server but I don't believe I can create the FK due to the composite key being made up of 3 columns.
How can I go about achieving this?
Yes, you can:
CREATE TABLE [dbo].[VariableMappings](
[ParentSurvey_ID] [nvarchar](4) NOT NULL,
[ReportingMonth] [nvarchar](6) NOT NULL,
[VariableName] [nvarchar](400) NOT NULL,
[Value] [int] NOT NULL,
PRIMARY KEY (ParentSurvey_ID, ReportingMonth, VariableName),
FOREIGN KEY (ParentSurvey_ID)
REFERENCES dbo.SurveyMaster (ID)
) ;
Mostly irrelevant to your problem, but having a PRIMARY KEY that is so wide (410 nvarchars) is not the best idea.
Your primary key definition and foreign key definitions are orthogonal. You can declare your composite primary key and your single column foreign key without issue. I would suggest to you, though, that a surrogate primary key on VariableMappings is better choice vs. the composite key - specifically for foreign keys pointing at VariableMappings.
There is one primary key that does matter and it is that of SurveyMaster. As long as ID is the primary key there, you can reference it from any number of other tables, regardless of those tables' primary keys.
A foreign key requires that the referenced combination of columns is unique, and the uniqueness must be guaranteed, for example by a primary key constraint.

Specify a Composite Foreign Key

I'm trying to create a Foreign Key out of two values in two different tables, some pointers would be appreciated!
Below is the code I am using for this :
CREATE TABLE [dbo].[EmployeeUnsetZone](
[EmployeeID] [char](2) NULL,
[ZoneOfficeID] [int] NOT NULL,
[ZoneID] [char](4) NULL
CONSTRAINT EmployeeUnsetZone_EmployeeFK FOREIGN KEY([EmployeeID],[ZoneID])
REFERENCES [Employee]([ID]), [ZoneByOffice]([ID])
)
I'd use:
CREATE TABLE [dbo].[EmployeeUnsetZone](
[EmployeeID] [char](2) NULL,
[ZoneOfficeID] [int] NOT NULL,
[ZoneID] [char](4) NULL,
PRIMARY KEY ([EmployeeID], [ZoneID]),
CONSTRAINT fk_employeeid FOREIGN KEY([EmployeeID]) REFERENCES [Employee]([ID]),
CONSTRAINT fk_zoneid FOREIGN KEY([ZoneID]) REFERENCES [ZoneByOffice]([ID])
)
The primary key will stop duplicates, and also setup the clustered key for the two columns to make searching against better.