In SQL Server , I got this error ->
SQL71516 :: The referenced table '[dbo].[PostsTags]' 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 don't understand why dint works foreign key, without them table created without problems, but I need a relationship between tables, in this location.I looked at other similar questions, but the answers were not found.
CREATE TABLE [dbo].[PostsTags] (
[PostId] INT NOT NULL,
[TegId] INT NOT NULL,
CONSTRAINT [PK_PostsTags] PRIMARY KEY CLUSTERED ([PostId] ASC, [TegId] ASC)
);
CREATE TABLE [dbo].[Comments] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[PostId] INT NOT NULL,
[DateTime] DATETIME NOT NULL,
[Name] NVARCHAR (64) NOT NULL,
[Body] NVARCHAR (MAX) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[Tags] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (64) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Tags_PostsTags] FOREIGN KEY ([Id]) REFERENCES [PostsTags]([TegId]) ON DELETE CASCADE
);
CREATE TABLE [dbo].[Posts] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (128) NOT NULL,
[DateTime] DATETIME NOT NULL,
[Body] NVARCHAR (MAX) NOT NULL,
[Avtor] NVARCHAR (64) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [Post_Tag] FOREIGN KEY ([Id]) REFERENCES [PostsTags]([PostId]) ON DELETE CASCADE,
CONSTRAINT [Post_Comment] FOREIGN KEY ([Id]) REFERENCES [Comments]([PostId]) ON DELETE CASCADE,
);
Sorry for bad English.
What you want is this, I'm sure:
CREATE TABLE [dbo].[Tags] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (64) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[Posts] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (128) NOT NULL,
[DateTime] DATETIME NOT NULL,
[Body] NVARCHAR (MAX) NOT NULL,
[Avtor] NVARCHAR (64) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[PostsTags] (
[PostId] INT NOT NULL,
[TagId] INT NOT NULL,
CONSTRAINT [PK_PostsTags] PRIMARY KEY CLUSTERED
([PostId] ASC, [TagId] ASC),
CONSTRAINT [FK_PostsTags_Tags] FOREIGN KEY ([TagId])
REFERENCES [Tags]([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_PostTags_Posts] FOREIGN KEY ([PostId])
REFERENCES [Posts]([Id]) ON DELETE CASCADE
);
CREATE TABLE [dbo].[Comments] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[PostId] INT NOT NULL,
[DateTime] DATETIME NOT NULL,
[Name] NVARCHAR (64) NOT NULL,
[Body] NVARCHAR (MAX) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Comments_Posts] FOREIGN KEY ([PostId])
REFERENCES [Posts](Id) ON DELETE CASCADE
);
That is - you can freely insert into Tags or Posts without consideration of any other tables or data within them. Once there's a row in Posts, you can start adding rows to Comments, provided that the PostId column contains a value that already exists in the Posts table's Id column (Comments references Posts)
Further, once there are rows in both Posts and Tags, only then can you insert rows into PostTags, with again constraints on what values are valid in that table being based on current rows in Posts and Tags.
Finally, I've left your CASCADE options set as in your original. If someone deletes a row from Posts then all rows in Comments that relate to that post are deleted. Similarly, any rows in PostsTags that relate to the post are deleted. If someone deletes a row from Tags then all rows in PostsTags that references that tag are removed.
Related
This is my first table :
CREATE TABLE [dbo].[County]
(
[CountyId] INT IDENTITY (1, 1) NOT NULL,
[County] VARCHAR(50) NOT NULL,
CONSTRAINT [PK_County] PRIMARY KEY CLUSTERED ([CountyId] ASC)
);
This is my second table :
CREATE TABLE [dbo].[Theatre]
(
[TheatreId] INT IDENTITY (1, 1) NOT NULL,
[TheatreName] VARCHAR(50) NOT NULL,
[CountyId] INT NOT NULL,
CONSTRAINT [PK_Theatre]
PRIMARY KEY CLUSTERED ([TheatreId] ASC),
CONSTRAINT [FK_Theatre_County]
FOREIGN KEY ([CountyId]) REFERENCES [dbo].[County] ([CountyId])
);
This is my third table :
CREATE TABLE [dbo].[Movies]
(
[CinemaId] INT NOT NULL,
[CategoryId] INT NOT NULL IDENTITY(101, 1),
[CinemaName] VARCHAR(50) NOT NULL,
[TheatreId] INT NOT NULL,
[ShowTimings] TIME (7) NOT NULL,
CONSTRAINT [PK_Movies]
PRIMARY KEY CLUSTERED ([CinemaId], [CategoryId]),
CONSTRAINT [FK_Movies_Theatre]
FOREIGN KEY ([TheatreId]) REFERENCES [dbo].[Theatre] ([TheatreId])
);
This is my last table:
CREATE TABLE [dbo].[Reviews]
(
[MovieId] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR(50) NOT NULL,
[Genres] VARCHAR(50) NOT NULL,
[Image] VARCHAR(50) NOT NULL,
[ShortDescription] TEXT NOT NULL,
[Rating] VARCHAR(50) NOT NULL,
[Grade] VARCHAR(50) NOT NULL,
[CategoryId] INT NOT NULL,
CONSTRAINT [PK_Reviews]
PRIMARY KEY CLUSTERED ([MovieId] ASC),
CONSTRAINT [FK_Reviews_Movies]
FOREIGN KEY ([CategoryId]) REFERENCES [Movies]([CategoryId]),
);
I have created a relationship between the tables yet I am getting an error while I am updating the last table:
SQL71516 :: The referenced table '[dbo].[Movies]' 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.
Can any about please tell me what is my mistake that I am doing?
Just like the error says, Movies.CategoryId is not a key, so you can't reference it in a Foreign Key. You need a Categories table that has CategoryId as its primary key. Then both Reviews and Movies can have a Foreign Key referencing Categories.
I have created 2 tables # CustomerHistory and # CustomerPaymentHistory
here is the sql syntax
CREATE TABLE [dbo].[CustomerHistory]
(
[ID] INT IDENTITY (1, 1) NOT NULL,
[HistoryID] AS ('CLI'+right('000000000'+CONVERT([varchar](10),[ID]),(5))) PERSISTED NOT NULL,
[CustomerID] INT NOT NULL,
[InvoiceNumber] NVARCHAR(30) NOT NULL,
[InvoiceDate] DATETIME NOT NULL,
[InvoiceTotal] NVARCHAR(20) NOT NULL,
[Balance] NVARCHAR(20) NOT NULL,
CONSTRAINT [PK_CUSTOMERHISTORY]
PRIMARY KEY CLUSTERED ([ID] ASC, [CustomerID] ASC),
CONSTRAINT [FK_CUSTOMER_CH]
FOREIGN KEY ([CustomerID]) REFERENCES [dbo].[Customers] ([ID])
)
and
CREATE TABLE [dbo].[CustomerPaymentHistory]
(
[ID] INT IDENTITY (1, 1) NOT NULL,
[PaymentID] AS ('CLI'+right('000000000'+CONVERT([varchar](10),[ID]),(5))) PERSISTED NOT NULL,
[HistoryID] INT NOT NULL,
[PaymentDate] DATETIME NOT NULL,
[PaymentAmount] NVARCHAR(20) NOT NULL,
[BalanceDue] NVARCHAR(20) NULL,
[PaidInFull] BIT NOT NULL,
CONSTRAINT [PK_CUSTOMERPAYMENTHISTORY]
PRIMARY KEY CLUSTERED ([ID] ASC, [HistoryID] ASC),
CONSTRAINT [FK_CUSTOMERHISTORY_CPH]
FOREIGN KEY ([HistoryID]) REFERENCES [dbo].[CustomerHistory] ([ID])
)
but when i'm trying to update the table, I get an error:
Update cannot proceed due to validation errors.
Please correct the following errors and try again.
SQL71516 :: The referenced table '[dbo].[CustomerHistory]' 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 can fix this problem?
I have a table that can be in a 1-* relationship with one of 2 different tables. I currently have it setup where there are 2 nullable columns that reference another table. However, this is causing an issue for cascade deletions.
CREATE TABLE [dbo].[TA] (
[Id] INT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_TA] PRIMARY KEY CLUSTERED ([Id] ASC),
);
CREATE TABLE [dbo].[TB] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[TAId] INT NOT NULL,
CONSTRAINT [FK_TB_To_TA] FOREIGN KEY ([TAId]) REFERENCES [dbo].[TA] ([Id]) ON DELETE CASCADE,
CONSTRAINT [PK_TB] PRIMARY KEY CLUSTERED ([Id] ASC),
);
CREATE TABLE [dbo].[TC] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[TAId] INT NULL,
[TBId] INT NULL,
CONSTRAINT [PK_TC] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_TC_To_TA] FOREIGN KEY ([TAId]) REFERENCES [dbo].[TA] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_TC_To_TB] FOREIGN KEY ([TBId]) REFERENCES [dbo].[TB] ([Id]), -- NOTE: DELETE CASCADE CAUSES A CIRCULAR REFERENCE
);
Essentially, this creates a nested structure like:
TA1
+ -- TC1, TC2
+ -- TB1
+ -- TC3, TC4
A TC object should only be a child of either TA or TB (not both). How should I go about developing this so that I can DELETE a TA row and have all TC and TB referenced rows deleted as well?
To resolve this I ended up breaking [TC] into multiple tables as described in a blog for entity framework. This created the following table structure:
CREATE TABLE [dbo].[TA] (
[Id] INT IDENTITY (1, 1) NOT NULL,
CONSTRAINT [PK_TA] PRIMARY KEY CLUSTERED ([Id] ASC),
);
CREATE TABLE [dbo].[TB] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[TAId] INT NOT NULL,
CONSTRAINT [FK_TB_To_TA] FOREIGN KEY ([TAId]) REFERENCES [dbo].[TA] ([Id]) ON DELETE CASCADE,
CONSTRAINT [PK_TB] PRIMARY KEY CLUSTERED ([Id] ASC),
);
CREATE TABLE [dbo].[TCA] (
[Id] INT IDENTITY (2, 2) NOT NULL,
[TAId] INT NULL,
CONSTRAINT [PK_TCA] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_TCA_To_TA] FOREIGN KEY ([TAId]) REFERENCES [dbo].[TA] ([Id]) ON DELETE CASCADE,
);
CREATE TABLE [dbo].[TCB] (
[Id] INT IDENTITY (1, 2) NOT NULL,
[TBId] INT NULL,
CONSTRAINT [PK_TCB] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_TCB_To_TB] FOREIGN KEY ([TBId]) REFERENCES [dbo].[TB] ([Id]) ON DELETE CASCADE,
);
I set the identities to even\odd values in order to prevent collision when creating a union of the two tables (see above link).
CREATE TABLE [dbo].[Book] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Auhor] NVARCHAR (50) NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
[Price] DECIMAL (18) NOT NULL,
[UserId] INT NOT NULL,
FOREIGN KEY ([UserId]) REFERENCES [dbo].[UserProfile] ([UserId])
);
CREATE TABLE [dbo].[UsedBook] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[BookId] INT NOT NULL,
[Email] NCHAR (10) NULL,
[MobileNumber] VARCHAR (15) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
FOREIGN KEY (BookID) REFERENCES [dbo].[Book]([Id])
);
Can you please give me correct syntax for foreign key command in the UsedBook table? Because every time I tried to run this it gives me error
SQL71516 :: The referenced table '[dbo].[Book]' 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.
And sorry for my english :)
Make [Id] in your Book table into a primary key:
[Id] INT IDENTITY (1, 1) NOT NULL PRIMARY KEY
I am using SQL Server 2012 and I have the following DDL:
CREATE TABLE [dbo].[Test] (
[TestId] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (100) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([TestId] ASC)
);
CREATE TABLE [dbo].[TestQuestion] (
[TestId] INT NOT NULL,
[TestQuestionId] INT NOT NULL,
[QuestionUId] CHAR (6) NOT NULL,
CONSTRAINT [PK_TestQuestion] PRIMARY KEY CLUSTERED ([TestId] ASC, [TestQuestionId] ASC),
CONSTRAINT [FK_TestQuestionTest] FOREIGN KEY ([TestId]) REFERENCES [dbo].[Test] ([TestId])
);
Is there a way I can make this so that when I delete a row in the Test table then all rows with that TestId are deleted from the TestQuestion table?
just provide ON DELETE CASCADE to your Foreign Key of Child Table(TestQuestion.TestId), so it will delete child record directly when parent record is deleted.
CREATE TABLE [dbo].[Test] (
[TestId] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (100) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([TestId] ASC)
);
CREATE TABLE [dbo].[TestQuestion] (
[TestId] INT NOT NULL,
[TestQuestionId] INT NOT NULL,
[QuestionUId] CHAR (6) NOT NULL,
CONSTRAINT [PK_TestQuestion] PRIMARY KEY CLUSTERED ([TestId] ASC, [TestQuestionId] ASC),
CONSTRAINT [FK_TestQuestionTest] FOREIGN KEY ([TestId]) REFERENCES [dbo].[Test] ([TestId]) ON DELETE CASCADE
);
Actually you can have many option with DELETE (and UPDATE also) like:
.
For Delete
ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
.
For Update
ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
As other commentators have said, the cascading foreign key is the best way to go. If you need more complicated logic, however, you could use a FOR DELETE trigger.