How to Relate 2 table with each other with 2 foreign keys - sql

Here is my code it generates Foreign key conflict error
CREATE TABLE tblProducts
(
ProductID int NOT NULL IDENTITY PRIMARY KEY,
ProductName nvarchar(30) NOT NULL,
BatchID int NOT NULL FOREIGN KEY REFERENCES tblBatches (BatchID)
)
CREATE TABLE tblBatches
(
BatchID INT NOT NULL IDENTITY PRIMARY KEY,
BatchCode nvarchar(20) NOT NULL,
Quantity int NOT NULL,
BatchMnf Date NOT NULL,
BatchExp Date NOT NULL,
PurchaseRate int NOT NULL,
SalesRate int NOT NULL,
ProductID int NOT NULL FOREIGN KEY REFERENCES tblProducts (ProductID)
)

You cannot do that. This is a circular reference.
This is a bad design but if you want to do that, you need to make foreign key columns Nullable.
CREATE TABLE tblProducts
(
ProductID int NOT NULL IDENTITY PRIMARY KEY,
ProductName nvarchar(30) NOT NULL,
BatchID int NULL FOREIGN KEY REFERENCES tblBatches (BatchID)
)
CREATE TABLE tblBatches
(
BatchID INT NOT NULL IDENTITY PRIMARY KEY,
BatchCode nvarchar(20) NOT NULL,
Quantity int NOT NULL,
BatchMnf Date NOT NULL,
BatchExp Date NOT NULL,
PurchaseRate int NOT NULL,
SalesRate int NOT NULL,
ProductID int NULL FOREIGN KEY REFERENCES tblProducts (ProductID)
)
Then you need to update reference fields after inserting records in tblBatches and tblProducts.
The good design says you need to create a bridge table like this:
CREATE TABLE tblProductsBatch
(
ID int NOT NULL IDENTITY PRIMARY KEY,
ProductID int NOT NULL,
BatchID int NOT NULL
)
And after inserting product and batch, you need to insert a record in this table to link rows to each other.

Related

LinqPad Syntax for adding foreign key constraint

This is the SQL I used in LinqPad:
CREATE TABLE Category
(
catID int NOT NULL,
catName NVARCHAR(150) NOT NULL,
catDesc NVARCHAR(150) NULL,
catCount int NOT NULL ,
CONSTRAINT category_pk PRIMARY KEY (catID)
);
CREATE TABLE InventoryTBLC
(
itemID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_items PRIMARY KEY,
itemName NVARCHAR(150) NOT NULL,
itemDesc NVARCHAR(150) NULL,
itemQuantity int,
itemPrice int,
imagePath NVARCHAR(300),
correctInsert NVARCHAR(300),
realImage image,
CONSTRAINT FK_category FOREIGN KEY (catID) REFERENCES Category(catID)
);
But I get the following error:
Invalid column ID. [ catID ]
Can someone help me with the LinqPad syntax?
If you want to use a column as the foreign key, you have to list that column in your table definition first! Adding the foreign key constraint does NOT add that column to your table!
And this is in no way Linqpad specific - this is standard SQL behavior.
So either you need to add catId to your second table like this:
CREATE TABLE InventoryTBLC
(
itemID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_items PRIMARY KEY,
itemName NVARCHAR(150) NOT NULL,
itemDesc NVARCHAR(150) NULL,
itemQuantity int,
itemPrice int,
imagePath NVARCHAR(300),
correctInsert NVARCHAR(300),
realImage image,
catID int NOT NULL, -- this column *MUST* exist to be used as FK
CONSTRAINT FK_category
FOREIGN KEY (catID) REFERENCES Category(catID)
);
or then maybe you want to use one of the other pre-existing columns in InventoryTBLC as your FK column?

Error relate SQL Server tables

I have the following problem: when we run the code, it displays the following error:
There are primary keys or candidates in the reference Ticket table
that match the list of referencing columns in foreign key '
FK__Payment__PkTicke__1A14E395
Code:
create table SystemUser
(
PkUser int identity(1,1),
UserLogin nvarchar(20) not null unique,
UserPassword nvarchar(50) not null,
UserName nvarchar(50) not null,
UserCpf nvarchar(50) not null,
UserBirth datetime not null,
UserGender nvarchar(15) not null,
AddressCep int not null,
AddressStreet nvarchar(50) not null,
AddressNumber nvarchar(20) not null,
AddressComplement nvarchar(50) not null,
AddressCity nvarchar(50) not null,
AddressState nvarchar(50) not null,
primary key(PkUser)
)
create table Attractions
(
PkAttraction integer identity(1,1) ,
AttractionName nvarchar(50) not null unique,
AttractionDate datetime not null,
AttractionDescription nvarchar(150) not null
primary key(PkAttraction)
)
create table Ticket
(
PkTicket int identity(1,1),
PkUser int not null,
PkAttraction int not null,
TicketPrice decimal not null,
primary key(PkTicket, PkUser, PkAttraction),
foreign key(PkUser) references SystemUser(PkUser),
foreign key(PkAttraction) references Attractions(PkAttraction)
)
create table Payment
(
PkPayment int identity(1,1),
PkTicket int not null,
Portion int not null,
IdTransaction nvarchar(100) not null,
Payday datetime not null,
primary key(PkPayment, PkTicket),
foreign key(PkTicket) references Ticket(PkTicket),
)
create table FormPayment
(
PkFromPayment int identity(1,1),
PkPayment int not null,
ShareValue decimal not null,
ExpirationDate datetime not null
primary key(PkFromPayment, PkPayment),
foreign key(PkPayment) references Payment(PkPayment),
)
Your Ticket table as a primary key made up from 3 columns:
create table Ticket
(
.....
primary key(PkTicket, PkUser, PkAttraction),
....
)
Any table that wants to reference that table Ticket must also provide all 3 columns for the foreign key.
You cannot reference only part of a primary key - if you want to reference it, you must have all columns that it contains - otherwise you cannot establish a FK relationship.
So you must add the PkUser and PkAttraction columns to your Payment table so that you can establish this FK relationship:
create table Payment
(
PkPayment int identity(1,1),
PkTicket int not null,
PkUser int not null, // add this
PkAttraction int not null, // add this
Portion int not null,
IdTransaction nvarchar(100) not null,
Payday datetime not null,
primary key(PkPayment, PkTicket),
// change to this
foreign key(PkTicket, PkUser, PkAttraction) references Ticket(PkTicket, PkUser, PkAttraction)
.....
)
When you not specify a name for FK and PK, SQL server generates a name. in this case, looks like SQL server generates duplicate name.
If you specify name for FK and PK, it will work.

Trouble Referencing Two-part Primary Key in SQL Server

I created this table with a two-part primary key:
Create Table Part
(PartNumber Int Not Null,
VendorNumber Int Not Null References Vendor(VendorNumber),
PartDescription VarChar(100) Not Null,
UnitPrice Money Not Null,
MTDSales Money Not Null,
YTDSales Money Not Null,
UnitsOnHand Int Not Null,
UnitsAllocated Int Not Null,
ReorderPoint Int Not Null,
VendorPrice Money Not Null,
MinimumOrderQuantity Int Not Null,
ExpectedLeadTime Datetime Not Null,
Primary Key (PartNumber, VendorNumber))
And another table is referencing the Part table's primary keys:
Create Table OrderDetail
(OrderNumber Int Not Null References Orders(OrderNumber),
SEQNumber Int Not Null,
PartNumber Int Not Null References Part(PartNumber),
VendorNumber Int Not Null References Part(VendorNumber),
NumberOrdered Int Not Null,
QuotedPrice Money Not Null,
LineTotal Int Not Null,
Comments VarChar(100) Not Null,
Primary Key (OrderNumber, SEQNumber))
When running the program, the following error is returned:
Msg 1776, Level 16, State 0, Line 99
There are no primary or candidate keys in the referenced table 'Part' that match the referencing column list in the foreign key 'FK__OrderDeta__PartN__239E4DCF'.
Could anyone provide suggestions on how to resolve the missing primary key error?
You need to create one composite foreign key, not two single-column keys. You can do it as a separate constraint in create table:
Create Table OrderDetail
(
OrderNumber Int Not Null References Orders(OrderNumber),
SEQNumber Int Not Null,
PartNumber Int Not Null,
VendorNumber Int Not Null,
NumberOrdered Int Not Null,
QuotedPrice Money Not Null,
LineTotal Int Not Null,
Comments VarChar(100) Not Null,
Primary Key (OrderNumber, SEQNumber),
constraint FK_OrderDetail_Part foreign key (PartNumber,VendorNumber)
references Part (PartNumber,VendorNumber)
)

Designing a rudimentary Shopping Cart database

create table [User]
(
UserId int primary key identity(1,1),
FirstName nvarchar(256) not null,
LastName nvarchar(256) not null,
)
create table Product
(
ProductId int primary key identity(1,1),
UnitPrice decimal(18,2) not null, //For catalog purposes.
Name nvarchar(1000) not null,
Description nvarchar(max) not null,
Stock int not null
)
create table [Order]
(
OrderId int primary key identity(1,1),
UserId int foreign key references [User](UserId),
ProductId int foreign key references Product(ProductId),
UnitCost decimal(18,2) not null, //How much it actually cost when the person bought it.
ItemCount int not null,
Subtotal decimal(18,2) not null
)
create table OrderDetail
(
OrderDetailId int primary key identity(1,1),
?
I'm stuck on the database design of the order system.
A user can choose n products to add to a order request. Any suggestions?
Following some advice given here, how would this feel? Any pitfalls?
create table [User]
(
UserId int primary key identity(1,1),
FirstName nvarchar(256) not null,
LastName nvarchar(256) not null,
)
create table Product
(
ProductId int primary key identity(1,1),
UnitPrice decimal(18,2) not null,
Name nvarchar(1000) not null,
Description nvarchar(max) not null,
Stock int not null
)
create table [Order]
(
OrderId int primary key identity(1,1),
UserId int foreign key references [User](UserId),
DateOfOrder datetime not null
)
create table OrderDetail
(
OrderDetailId int primary key identity(1,1),
OrderId int foreign key references [Order](OrderId),
ProductId int foreign key references Product(ProductId),
UnitCost decimal(18,2) not null,
ItemCount int not null,
Subtotal decimal(18,2) not null
)
Typically, you'd have the Order table with the top-level order information (who, when etc) and then an OrderItem (or OrderDetail) table which has a row for each product that forms part of the order including columns like:
OrderId
ProductId
Quantity
etc
Good candidate for a PK on this OrderItem/OrderDetail table would be on OrderId + ProductId.
So where you have columns like ProductId, UnitCost, ItemCount etc in the Order table, those are in the wrong place and should be in the OrderItem/OrderDetail table.
Update:
To set up a compound PK, you can do:
create table OrderDetail
(
OrderId int foreign key references [Order](OrderId),
ProductId int foreign key references Product(ProductId),
...other columns...,
CONSTRAINT PK_OrderDetail PRIMARY KEY(OrderId, ProductId)
)

T-SQL: CHECK constraint not working

I have the following T-SQL schema. The problem I am having is that the check constraint on the Download table is not working. I am still able to insert records into that table that contain NULL values for both ProductId and CategoryId. Why is this so?
I want both the ProductId and CategoryId columns to allow NULL values, but for any given record only one of these are allowed to be set to NULL, the other needs to be a corresponding Id of the Category or Product table.
CREATE TABLE Category (
Id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
Description nvarchar(100) NULL,
ParentCategoryId int NULL
CONSTRAINT fk_CategoryId_CategoryId FOREIGN KEY (Id) REFERENCES Category(Id)
)
GO
CREATE TABLE Product (
Id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
Title nvarchar(100) NOT NULL,
TagLine nvarchar(MAX) NOT NULL,
Description nvarchar(MAX)NULL,
CategoryId int NOT NULL,
ImageUrl nvarchar(255) NULL,
Keywords nvarchar(200) NOT NULL
CONSTRAINT fk_ProductCategoryId_CategoryId FOREIGN KEY (CategoryId) REFERENCES Category(Id)
)
GO
CREATE TABLE Download (
Id int IDENTITY(1,1) NOT NULL PRIMARY KEY,
Title nvarchar(100) NOT NULL,
Description nvarchar(MAX) NULL,
CategoryId int NULL,
ProductId int NULL,
DownloadUrl nvarchar(255) NOT NULL,
CONSTRAINT fk_DownloadCategoryId FOREIGN KEY (CategoryId) REFERENCES Category(Id),
CONSTRAINT fk_DownloadProductId FOREIGN KEY (ProductId) REFERENCES Product(Id),
CONSTRAINT chk_ReferencesCategoryOrProduct CHECK (ProductID != NULL AND CategoryId != NULL)
)
GO
Use:
CONSTRAINT chk_ReferencesCategoryOrProduct CHECK (ProductID IS NOT NULL
OR CategoryId IS NOT NULL)
NULL isn't a value -- it's a placeholder for the lack of a value. Which is why you need to use specific syntax to check for it.