Billing Database - sql-server

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?

Related

Table contains no primary or candidate keys that match the referencing column list in the foreign key

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.

Query to Return a value from a linked table in sql

I'm trying to develop an app for a driving school.
I have a table for instructors:
CREATE TABLE [dbo].[Instructori]
(
[nume] NVARCHAR(50) NOT NULL,
[prenume] NVARCHAR(50) NOT NULL,
[CNP] CHAR(13) NOT NULL,
[Nastere] SMALLDATETIME NOT NULL,
[Angajare] SMALLDATETIME NOT NULL,
[IDmasina] INT NOT NULL,
[IDCategorie] INT NOT NULL,
[Sex] NCHAR(1) NOT NULL,
[NrStudenti] INT NULL DEFAULT 0,
[RataPromovare] DECIMAL(5, 2) NULL DEFAULT 0,
[TotalStudenti] AS [dbo].Total_Stud(CNP),
CONSTRAINT [PK_Instructori] PRIMARY KEY CLUSTERED ([CNP] ASC),
CONSTRAINT [Instr]
FOREIGN KEY ([IDCategorie]) REFERENCES [dbo].[Categorie] ([IDCategorie]),
);
One for Students:
CREATE TABLE [dbo].[Studenti]
(
[nume] NVARCHAR(50) NOT NULL,
[prenume] NVARCHAR(50) NOT NULL,
[Nastere] SMALLDATETIME NOT NULL,
[Legislatie_p] INT NULL,
[Categorii_dobandite] NVARCHAR(50) NULL,
[Categorie] INT NOT NULL,
[Data_examnen] SMALLDATETIME NOT NULL,
[IDLectie] INT NOT NULL,
[CNP] CHAR(13) NOT NULL,
[CNPI] CHAR(13) NOT NULL,
CONSTRAINT [PK_Studenti] PRIMARY KEY CLUSTERED ([CNP] ASC),
CONSTRAINT [FK_Categorie]
FOREIGN KEY ([Categorie]) REFERENCES [dbo].[Categorie] ([IDCategorie]),
CONSTRAINT [Lectie]
FOREIGN KEY ([IDLectie]) REFERENCES [dbo].[Legislatie] ([IDLectie]),
CONSTRAINT [Instructor1]
FOREIGN KEY ([CNPI]) REFERENCES [dbo].[Instructori] ([CNP])
);
and one for cars named "Masina" which is not really relevant.
"Conducere" is the linking table between the 3 others, and it's only used to count how many hours each student drive.
CREATE TABLE [dbo].[Conducere]
(
[CNP_Instructor] CHAR(13) NOT NULL,
[IDMasina] INT NOT NULL,
[CNP_Student] CHAR(13) NOT NULL,
[Numar_ore] INT NOT NULL DEFAULT 0,
PRIMARY KEY CLUSTERED ([CNP_Instructor] ASC),
CONSTRAINT [Student]
FOREIGN KEY ([CNP_Student]) REFERENCES [dbo].[Studenti] ([CNP]),
CONSTRAINT [FK_Masina]
FOREIGN KEY ([IDMasina]) REFERENCES [dbo].[Masina] ([IDMasina]),
CONSTRAINT [Instructor]
FOREIGN KEY ([CNP_Instructor]) REFERENCES [dbo].[Instructori] ([CNP])
);
I already coded a function for the total number of students for each instructor.
CREATE FUNCTION dbo.Total_Stud(#CNP CHAR(13))
RETURNS INT
AS
BEGIN
RETURN
(SELECT Count(CNP)
FROM Studenti
WHERE CNPI = #CNP)
END
I'm trying to find the students that have the same instructor(based on their CNP) and did not drive 30h yet. Students still in school ish.
You can SUM the hours for each student and filter the results by HAVING:
CREATE FUNCTION dbo.Student_Below_RequiredHours(#CNP CHAR(13),#RequiredHours int)
RETURNS TABLE
AS
BEGIN
RETURN
(SELECT CNP_Student
FROM [dbo].[Conducere]
WHERE CNP_Instructor = #CNP
GROUP BY CNP_Student
HAVING SUM([Numar_ore])<#RequiredHours)
END

Correct Syntax to Declare Foreign Key

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

How can I set up my SQL so that a delete on a parent deletes child rows?

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.

FOREIGN KEY: contains no primary or candidate keys

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.

Resources