ERROR Column CHECK constraint for column references another column - sql

I use MS SQL 2008 R2, I need create a Table with a CHECK on a specific column but I receive this error. Could you please point me out in the right direction? Thanks
HeatingSystem tinyint NOT NULL
CONSTRAINT CK_ReProperties_HeatingSystem CHECK(Size between 0 and 3),
ERROR
Msg 8141, Level 16, State 0, Line 1
Column CHECK constraint for column 'HeatingSystem' references another column, table 'ReProperties'.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.

Constraints that are defined inline at column level can only reference the column they are defined next to.
Either move the constraint definition next to the correct column or move the constraint definition to the end of the table definition.
Fails
CREATE TABLE HeatingSystem
(
Size INT,
HeatingSystem TINYINT CHECK(Size between 0 and 3)
)
Succeeds
CREATE TABLE HeatingSystem
(
Size INT CHECK(Size between 0 and 3),
HeatingSystem TINYINT
)
Also Succeeds
CREATE TABLE HeatingSystem
(
Size INT ,
HeatingSystem TINYINT,
CHECK(Size between 0 and 3 AND HeatingSystem BETWEEN 1 AND 10)
)
The final way also allows you to declare a row level constraint referencing multiple columns.

With your comment, I don't understand where "Size" is coming from...
Can't you just make
CONSTRAINT CK_ReProperties_HeatingSystem CHECK(HeatingSystem between 0 and 3)

Here how I have solved.
HeatingSystem tinyint NOT NULL
CONSTRAINT CK_ReProperties_HeatingSystem CHECK(HeatingSystem between 0 and 3),

I tried your query and it is giving me error as Invalid column name 'Size'. You should write the columnname - HeatingSystem in place of size. Use the following:-
HeatingSystem tinyint NOT NULL
CONSTRAINT CK_ReProperties_HeatingSystem CHECK(HeatingSystem between 0 and 3),

You may be just missing a comma separator before the word CONSTRAINT !!
e.g.) if "," after ([WorkLocationId]) in below snippet is missing then, it will throw ERROR Column CHECK constraint for column references another column error.
This will throw error -
CREATE TABLE [MYSYSTEM].[User](
[UserId] int Primary key NOT NULL,
[UserName] [nvarchar](50) NULL,
[UserStatus] [nvarchar](1) NULL,
[CreatedDate] [Datetime] NOT NULL,
[WorkLocationId] int NOT NULL Foreign Key References [HRSYSTEM].[WorkLocations]([WorkLocationId])
CONSTRAINT [_UserStatusValues] CHECK ([UserStatus] IN ('A','I') )
)
This will work -
CREATE TABLE [MYSYSTEM].[User](
[UserId] int Primary key NOT NULL,
[UserName] [nvarchar](50) NULL,
[UserStatus] [nvarchar](1) NULL,
[CreatedDate] [Datetime] NOT NULL,
[WorkLocationId] int NOT NULL Foreign Key References [HRSYSTEM].[WorkLocations]([WorkLocationId]),
CONSTRAINT [_UserStatusValues] CHECK ([UserStatus] IN ('A','I') )
)

Just use a table level constraint, i.e move the constraint to the end of the table definition.

Related

Error during foreign key creation: Invalid references

I have 2 tables and I want to create a foreign key constraint in the second table. This is what I tried:
Table 1:
CREATE TABLE REMINDER_RULE_M
(
REMINDER_RULE_M_D int IDENTITY(1,1) NOT NULL,
COMMUNICATION_MODE nvarchar(255) NOT NULL,
REMINDER_TO nvarchar(255) NOT NULL,
REMINDER_VALUE varchar(255) NOT NULL,
REMINDER_CONDITION varchar(255) NOT NULL,
REMINDER_TO_CUSTOM varchar(255)
)
Table 2:
CREATE TABLE REMINDER_AUDIT
(
REMINDER_AUDIT_D int IDENTITY(1,1) NOT NULL,
ACTION varchar(255) NOT NULL,
CONSTRAINT FK_b892318b20e5bbe162722ea5946
FOREIGN KEY (REMINDER_RULE_M_D)
REFERENCES REMINDER_RULE_M(REMINDER_RULE_M_D),
OLD_VALUE nvarchar(1024) NOT NULL,
NEW_VALUE nvarchar(1024) NOT NULL,
)
I get an error running the second SQL query:
Reason:
SQL Error [1769] [S0001]: Foreign key 'FK_b892318b20e5bbe162722ea5946' references invalid column 'REMINDER_RULE_M_D' in referencing table 'REMINDER_AUDIT'.
As the error clearly tells you - you don't have a column in your second table.
You must have a column in order to create a FK constraint - the FK constraint does NOT create a column in your table - it just establishes a constraint between existing tables and columns.
So try this for your second table:
CREATE TABLE REMINDER_AUDIT
(
REMINDER_AUDIT_D int IDENTITY(1,1) NOT NULL,
ACTION varchar(255) NOT NULL,
-- define the column!
REMINDER_RULE_M_D int NOT NULL,
-- I'd strongly recommend trying to come up with a more
-- intuitive and useful naming convention for your FK constraints!
CONSTRAINT FK_b892318b20e5bbe162722ea5946
FOREIGN KEY (REMINDER_RULE_M_D)
REFERENCES REMINDER_RULE_M(REMINDER_RULE_M_D),
OLD_VALUE nvarchar(1024) NOT NULL,
NEW_VALUE nvarchar(1024) NOT NULL,
)
I just guessed that REMINDER_RULE_M_D is NOT NULL - you might need to adapt this (if it's an optional key).
You do not need to write Foreign Key
CREATE TABLE REMINDER_AUDIT (
REMINDER_AUDIT_D int IDENTITY(1,1) NOT NULL,
ACTION varchar(255) NOT NULL,
CONSTRAINT FK_b892318b20e5bbe162722ea5946 REFERENCES REMINDER_RULE_M(REMINDER_RULE_M_D),
OLD_VALUE nvarchar(1024) NOT NULL,
NEW_VALUE nvarchar(1024) NOT NULL,
)

Reference a foreign key and Add check constraint for column in parent table

How can I Add to the Table BusinessCategories a check that the column IsBusinessCategory value is 'true' for the related Categories.ID?
CREATE TABLE [dbo].[Categories](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NULL,
[DisplayNameHe] [nvarchar](400) NOT NULL,
[DisplayNameEn] [nvarchar](400) NOT NULL,
[DisplayNameEs] [nvarchar](400) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[Status] [bit] NOT NULL,
[IsBusinessCategory] [bit] NULL
)
CREATE TABLE [dbo].[BusinessCategories](
[ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[BusinessCategoryID] [INT] NOT NULL REFERENCES Categories(ID) -- Need to check that is
businessCategory ==1
[BusinessID] [INT] NOT NULL REFERENCES Business(ID)
)
The goal is to be able to insert to the column BusinessCategoryID only values from Categories table that has IsBusinessCategory == true.
I don't recommend that kind of solution, that should be done in the application's business layer
In SQL side there is a tricky way, not optimal, but doable...
First create an scalar function that returns the isBusinessCategory value of the selected category
CREATE FUNCTION fn_isBusinessCategory (#CatID INT) RETURNS INT
AS
BEGIN
RETURN (SELECT isBusinessCategory FROM Categories WHERE CategoryID = #CatID)
END
GO
Create another scalar function that returns 1 if a given category is referenced in BusinessCategories
CREATE FUNCTION fn_isBusinessCategoryValid (#CatID INT, #isBusinessCat BIT) RETURNS BIT
AS
BEGIN
IF #isBusinessCat = 1
RETURN 1
ELSE IF EXISTS (SELECT 1 FROM BusinessCategories WHERE CategoryID = #CatID)
RETURN 0
ELSE
RETURN 1
END
GO
Add the following constraints
Step 1 Foreign key to validate integrity between two tables
ALTER TABLE BusinessCategories ADD CONSTRAINT FK_BusinessCategory
FOREIGN KEY (CategoryID)
REFERENCES Categories (CategoryID)
Step 2 Check constraint to validate that category is_businessCategory
ALTER TABLE BusinessCategories ADD CONSTRAINT ck_BusinessCategory
CHECK (dbo.fn_isBusinessCategory(CategoryID) = 1)
Step 3 Check constraint to prevent a category to be changed as non businessCategory when is used
ALTER TABLE Categories ADD CONSTRAINT ck_Category_isBusinessCategory
CHECK (dbo.fn_isBusinessCategoryValid(CategoryID, isBusinessCategory) = 1)
The goal is to be able to insert to the column BusinessCategoryID only
values from Categories table that has IsBusinessCategory == true.
You can do this much by writing a UDF that takes BusinessCategoryID as a parameter and queries the Categories table to get the value of IsBusinessCategory. The CHECK constraint would simply test whether the returned value of the parameter is true or false.
Be warned however, that this constraint will only be checked when you add rows to the BusinessCategories table. If someone changes the value of IsBusinessCategory in the Categories table, the CHECK constraint will not catch it. You would need to put a separate constraint on the Categories table to catch that.

There are no primary or candidate keys in the referenced table ... that match the referencing column list in the foreign key

I am getting this error while creating the table [dbo].[WeibullSummaryDetails].
These are my two tables
CREATE TABLE [dbo].[WeibullFilterDetails]
(
[WeibullFilterDetailsId] [int] IDENTITY(1,1) NOT NULL,
[ProjectTeamId] int not null,
[WeekStartDate] date not NULL,
[WeekEndDate] date not null ,
[IsRefreshed] bit NULL,
CONSTRAINT FK_WeibullFilterDetails_WeibullFilterDetails
FOREIGN KEY ([ProjectTeamId])
REFERENCES [dbo].[ProjectTeams]([Id]),
PRIMARY KEY ([ProjectTeamId], [WeibullFilterDetailsId])
)
CREATE TABLE [dbo].[WeibullSummaryDetails]
(
[WeibullSummaryDetailsId] [int] IDENTITY(1,1) NOT NULL,
[WeibullFilterDetailsId] int not null,
[ProjectTeamId] int not null,
[ActualEstimatedBugCount] int NULL,
[CurrentBugCount] int NULL,
[PercentageBugFound] float NULL,
[PercentageBugResolved] float NULL,
[BugsToFind] int NULL,
BugsToResolve int NULL,
LinearEquation nvarchar(100) null,
RSquare float NULL,
Shape float NULL,
Scale float NULL
PRIMARY KEY ([WeibullSummaryDetailsId], [WeibullFilterDetailsId],[ProjectTeamId]),
CONSTRAINT FK_WeibullSummaryDetails_WeibullFilterDetails
FOREIGN KEY ([WeibullFilterDetailsId],[ProjectTeamId])
REFERENCES [dbo].[WeibullFilterDetails]([WeibullFilterDetailsId],[ProjectTeamId])
)
Detailed error message
Msg 1776, Level 16, State 0, Line 14
There are no primary or candidate keys in the referenced table 'dbo.WeibullFilterDetails' that match the referencing column list in the foreign key 'FK_WeibullSummaryDetails_WeibullFilterDetails'.
Msg 1750, Level 16, State 0, Line 14
Could not create constraint. See previous errors.
I have seen other posts on this error, usually the solution given is that if parent table has a composite key, then both the columns should be present in the child table too and should be used for the foreign key constraint.
That is exactly what I am doing here, but still getting this error.
Help is greatly appreciated!
For [dbo].[WeibullFilterDetails] you defined the primary key as ([ProjectTeamId],[WeibullFilterDetailsId]), yet in your REFERENCES clause you wrote ([WeibullFilterDetailsId],[ProjectTeamId]) -- the order doesn't match. Try:
CREATE TABLE [dbo].[WeibullSummaryDetails](
...
FOREIGN KEY ([ProjectTeamId],[WeibullFilterDetailsId])
REFERENCES [dbo].[WeibullFilterDetails]([ProjectTeamId],[WeibullFilterDetailsId])
);

SQL on Azure - using a computed column as a primary key index

I am not sure what is wrong with the below SQL.
I used to have a primary key based off of the customer_reference_no.
They now have some duplicates so I am creating a column called uniquePoint that is a combination of customer_no, customer_reference_no and stop_zip.
The below works fine:
CREATE TABLE [dbo].[stop_address_details] (
[customer_no] NCHAR (5) NOT NULL,
[customer_reference_no] VARCHAR (20) NOT NULL,
[stop_name] VARCHAR (40) NOT NULL,
[stop_address] VARCHAR (40) NULL,
[stop_city] VARCHAR (30) NULL,
[stop_state] CHAR (2) NULL,
[stop_zip] VARCHAR (10) NULL,
[point_no] VARCHAR (20) NULL,
[branch_id] VARCHAR (6) NULL,
[delivery_route] VARCHAR (10) NULL,
[dateTimeCreated] DATETIME NULL,
[dateTimeUpdated] DATETIME NULL,
[estimated_delivery_time] TIME (0) NULL,
[est_del_time] DATETIME NULL,
[dateTimeLastUsedInDatatrac] DATETIME NULL,
[uniquePoint] as customer_no + '_' + customer_reference_no + '_' + stop_zip PERSISTED ,
CONSTRAINT [AK_stop_address_details_customer_reference_no] UNIQUE NONCLUSTERED ([customer_reference_no] ASC),
CONSTRAINT [PK_stop_address_details] PRIMARY KEY ([uniquePoint])
But when I remove the constraint for customer_reference_no I get the following error:
SQL71516 :: The referenced table '[dbo].[stop_address_details]' 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.
I am referencing the computed column and it is persisted.
Not sure what is missing?
Thank you,
Joe
The answer appears to be that I have another table that is referencing this table with a foreign key:
REATE TABLE [dbo].[rep_assigned_stop_matrix] (
[customer_reference_no] VARCHAR (20) NOT NULL,
[rep_id] INT NULL,
[dateTimeCreated] DATETIME NULL,
[sendSMS] BIT NULL,
[sendEmail] BIT NULL,
[id] INT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_rep_assigned_stop_matrix] PRIMARY KEY CLUSTERED ([id] ASC),
CONSTRAINT [AK_rep_assigned_stop_matrix_Column] UNIQUE NONCLUSTERED ([customer_reference_no] ASC, [rep_id] ASC),
CONSTRAINT [FK_pod_update_lookup_rep_info] FOREIGN KEY ([rep_id]) REFERENCES [dbo].[rep_info] ([id]) ON DELETE CASCADE,
CONSTRAINT [FK_lookup_Stop_Details] FOREIGN KEY ([customer_reference_no]) REFERENCES [dbo].[stop_address_details] ([customer_reference_no])
);
When this bottom constrain was removed the error went away. What I don't understand is why the error message was not a bit clearer (meaning naming the rep_assigned_stop_matrix table) -- or am I still missing something?
Joe
It seems that your '[dbo].[stop_address_details]' is still referring to the customer_reference_no column. Try Remove and re-add it using the new column name.

Add nullable datetime column to Primary Key

I have a table with following columns:
[ClauseID] [int] NOT NULL,
[PolicyCategoryID] [int] NOT NULL,
[ExpiryDate] [smalldatetime] NULL,
By now ClauseID and PolicyCategoryID together creates the primary key. But I want ExpiryDate also be a part of primary key. To make the column not null I tried the following but it gives an error:
ALTER TABLE tblClauses_PolicyCategory
ALTER COLUMN [ExpiryDate] SMALLDATETIME NOT NULL DEFAULT '2079-06-06'
Incorrect syntax near the keyword 'DEFAULT'.
Any idea why? Is it not possible to set a default date like this?
EDIT: By bad! Default key was already set. That must be the reason it gave an error.
try this:
ALTER TABLE tblClauses_PolicyCategory
ALTER COLUMN [ExpiryDate] SMALLDATETIME NOT NULL
ALTER TABLE tblClauses_PolicyCategory ADD CONSTRAINT
cons_expiryDate DEFAULT '2079-06-06' FOR ExpiryDate
Before execute these lines, please check if exists some rows with ExpiryDate null, if yes, please, update all nullable rows to default value
I think this will help you:
CREATE TABLE tblClauses_PolicyCategory(
[ClauseID] [int] NOT NULL,
[PolicyCategoryID] [int] NOT NULL,
[ExpiryDate] [smalldatetime] NULL)
ALTER TABLE tblClauses_PolicyCategory
ALTER COLUMN [ExpiryDate] SMALLDATETIME NOT NULL
ALTER TABLE tblClauses_PolicyCategory
ADD CONSTRAINT cons_default DEFAULT '2079-06-06' FOR ExpiryDate
But, before changing ExpireDate to NOT NULL, you must populate values for existing rows in this column, and then change column to NOT NULL.