creating tables in visual studio sql - sql

i get this error when i execute
SQL71516 :: The referenced table '[dbo].[Stock]' 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.
CREATE TABLE [dbo].[Customer]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[FirstName] NCHAR(10) NOT NULL,
[LastName] NCHAR(10) NOT NULL,
[Email] NCHAR(10) NOT NULL UNIQUE,
[Mobile] NCHAR(10) NOT NULL
)
CREATE TABLE [dbo].[Stock]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[name] NCHAR(10) NOT NULL,
[price] INT NOT NULL,
CustomersID int NOT NULL,
FOREIGN KEY (CustomersID) REFERENCES Customer(Id)
ON DELETE CASCADE ON UPDATE CASCADE
)
CREATE TABLE [dbo].[Order]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Date] DATE NOT NULL,
[Quantity] INT NOT NULL,
Stock_price int NOT NULL,
[Total Value] AS (Quantity)*(Stock_price) PERSISTED,
CONSTRAINT [FK_Stock_price1] FOREIGN KEY ([Stock_price])
REFERENCES [Stock](price) ON DELETE CASCADE ON UPDATE CASCADE
)

You can only use columns that are uniquely indexed. The price column is not. However, I suspect that the foreign key that's giving you a hard time is actually wrong anyway. I also don't think you should have a CustomerId reference in your Stock table.
in fact, the basic standard database structure for a store is this:
Customer table
id, name [, other details]
Stock table
id, name, price [, other details]
Order table
id, customer id, order date [, other details]
Order details table
id, order id, item id, quantity, price [, other details]
This way, an order is related to a single customer, an can contain multiple items.
The price column in the order details table represents the item price at the date of the order - while the price column in the stock table represents the item's current price.

[Stock].[price] is not a key, that's why you can't define a foreign key on that column.
If 2 products (A and B) in table Stock have the same price, what would be the reference?
You can either set a key on this column, such as UNIQUE but this will prevent you to have differents prices in your table Stock.
I suggest you to use the [Stock].[Id] key as reference for your foreign key, such as :
CREATE TABLE [dbo].[Order]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Date] DATE NOT NULL,
[Quantity] INT NOT NULL,
Stock_id int NOT NULL, -- <--- changed column name
[Total Value] AS (Quantity)*(Stock_price) PERSISTED,
CONSTRAINT [FK_Stock_id1] FOREIGN KEY ([Stock_id]) -- <-- changed column name
REFERENCES [Stock](Id) ON DELETE CASCADE ON UPDATE CASCADE
-- ^--^------------------------------------- Notice this
);

Related

Can have in my case foreign key duplicated value?

can have in this case foreign key duplicated value? Or better just have an index on column?
Here is my table structure:
CREATE TABLE customers(
id INT (10) NOT NULL,
name VARCHAR (50) NOT NULL,
city VARCHAR (50) NOT NULL
);
CREATE TABLE orders(
cus_id INT (10) NOT NULL ,
order_date DATETIME NOT NULL
);
CREATE TABLE products(
id INT (5) NOT NULL,
product_name VARCHAR(50) NOT NULL,
product_price INT(10) NOT NULL
);
But in orderitems table (Where I have stored the ordered products, the customer can have multiple products ordered so the foreign key value (cus_id) can be duplicated)
CREATE TABLE ordered_items(
id INT (10) NOT NULL,
cus_id INT (10) NOT NULL,
product_id INT(5) NOT NULL
);
ALTER TABLE customers ADD CONSTRAINT customer_id PRIMARY KEY ( id ) ;
ALTER TABLE orders ADD CONSTRAINT customers_id_fr FOREIGN KEY ( cus_id ) REFERENCES customers ( id );
ALTER TABLE ordered_items ADD CONSTRAINT ordered_items_fr FOREIGN KEY ( cus_id ) REFERENCES customers ( id );
EDIT:
Sorry the ordered_items table have a unique ID column as well.
Yes! you can have multiple value of cus_id inside ordered_items. however, your intention is better served if you replace cus_id by order_id from orders, Thus your relationship would sound like,
a **customer** can have multiple *orders*,
an **order** can have multiple *order items*,
and an **order item** can only have single *product*
your sql would look like this
CREATE TABLE customers(
id INT (10) NOT NULL,
name VARCHAR (50) NOT NULL,
city VARCHAR (50) NOT NULL
);
ALTER TABLE customers ADD CONSTRAINT customer_id PRIMARY KEY ( id ) ;
CREATE TABLE orders(
id INT (5) NOT NULL,
cus_id INT (10) NOT NULL ,
order_date DATETIME NOT NULL
);
ALTER TABLE orders ADD CONSTRAINT order_id PRIMARY KEY ( id ) ;
ALTER TABLE orders ADD CONSTRAINT customers_id_fr FOREIGN KEY ( cus_id ) REFERENCES customers ( id );
CREATE TABLE products(
id INT (5) NOT NULL,
product_name VARCHAR(50) NOT NULL,
product_price DOUBLE NOT NULL
);
ALTER TABLE products ADD CONSTRAINT product_id PRIMARY KEY ( id ) ;
CREATE TABLE ordered_items(
id INT (10) NOT NULL,
order_id INT (10) NOT NULL,
product_id INT(5) NOT NULL
);
ALTER TABLE ordered_items ADD CONSTRAINT ordrItm_id PRIMARY KEY ( id ) ;
ALTER TABLE ordered_items ADD CONSTRAINT ordrItm_order_frK FOREIGN KEY ( order_id ) REFERENCES orders ( id );
ALTER TABLE ordered_items ADD CONSTRAINT ordrItm_prd_frK FOREIGN KEY ( product_id) REFERENCES products ( id );

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

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.

Nested cursor, While Loop SQL

I am trying to insert data into two tables(at one shot 100 to 150 rows on both tables). First Table Primary key have a reference with Second Table Foreign key.I Read that Cursor is having problem for ##Fetch_Status is global variable. Which is best way to loop and do data insertion in both tables Cursor or While Loop or any other.
CREATE TABLE Table1
(
FirstTablePK [int] NOT NULL, --Mannual Increment(Not Identity)
Description [varchar](100) NOT NULL,
CONSTRAINT PK_Table1 PRIMARY KEY CLUSTERED (FirstTablePK)
)
CREATE TABLE Table2
(
SecondTablePK [int] NOT NULL, --Mannual Increment(Not Identity)
FirstTablePK [int] NOT NULL, -- Foreign Key Reference with Table1
Description [varchar](100) NOT NULL,
CONSTRAINT PK_Table2 PRIMARY KEY CLUSTERED (SecondTablePK),
CONSTRAINT FK_Table1 FOREIGN KEY (FirstTablePK) REFERENCES Table1(FirstTablePK)
)
Thanks in Advance.
Hari
A cursor is not often used to look up foreign keys. It's faster and easier to use a set-based query:
insert into SaleOrder
(remarks, product_id, customer_id, ...)
select 'please deliver fast'
, (select id from Products where name = 'Car Oil')
, (select id from Customers where name = 'India Corp')
, ...

Alter Table syntax Assignment

I have Assignment due in which i'm stuck on a question.
Add a “Sales Detail” table to your database. This table is related to the Orders and Products tables. It shows the product and quantity ordered at least (add other fields if you wish but explain why you added them on your paper).
There is no description of this table on the diagram provided. Use your best database design skills here!
Create Table SalesDetail
(
SaleDetailID int,
ProductID char(5),
ManufactureID char(3) not null,
OrderNo int,
qtyOrdered int
PRIMARY
)
Alter Table SalesDetail
Add FOREIGN KEY (ProductID)
REFERENCES Products(ProductID)
My Error is I can not get it to link SalesDetail table to Products table.
Msg 1776, Level 16, State 0, Line 1
There are no primary or candidate keys in the referenced table 'Products' that match the referencing column list in the foreign key 'FK__SalesDeta__Produ__5EBF139D'.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.
Create Table Customers
(
CustomerNo char(4)
Constraint ck_CustomerNoHas4positionsWithNumbers
Check(CustomerNo like'[0-9],[0-9],[0-9],[0-9]'),
Company varchar(50) not null,
CustomerRep char(3),
CreditLimt money default(20000.00),
PRIMARY KEY(CustomerNo)
)
Create Table Salesreps
(
EmployeeNo char(3)
Constraint ck_EmployeeNoHasDigits check(EmployeeNo like'[0-9],[0-9],[0-9]'),
FirstName varchar(25) not null,
LastName varchar(25) not null,
Age int,
SalesRepOffice char(2) not null,
Title varchar(50),
HireDate Date not null,
Manager char(3) not null,
Quota money,
Sales money not null,
PRIMARY KEY(EmployeeNo)
)
Create Table Offices
(
Office char(2) Constraint ck_checkOfficeHasNumbersOnly check(Office like'[0-9],[0-9]'),
City varchar(25) not null,
Region varchar(10) not null,
Manager char(3) not null,
Target money,
Sales money not null
PRIMARY KEY(Office)
)
Create Table Orders
(
OrderNo int,
OrderDate Date not null,
CustomerNo char(4) not null,
SalesRep char(3) not null
PRIMARY KEY(OrderNo)
)
Create Table Products
(
ManufactureID char(3)
Constraint ck_ManufactureIDifItHasLettersOnly check(ManufactureID like'[a-z],[a-z],[a-z]'),
ProductID char(5)
Constraint ck_ProductIDhasTwoLettersAndThreeNumbers check(ProductID like'[0-9],[0-9],[a-z],[a-z],[a-z]'),
Description varchar(50) not null,
Price money not null,
QtyOnHand int not null,
PRIMARY KEY(ManufactureID, ProductID)
)
--Add Foreign Keys to all tables who needs them
Alter Table Customers
Add constraint fk_customerrep
FOREIGN KEY (CustomerRep)
REFERENCES Salesreps(EmployeeNo)
Alter Table Salesreps
Add constraint fk_salesrepoffice
FOREIGN KEY (SalesRepOffice)
REFERENCES Offices(Office),
constraint fk_manager
FOREIGN KEY (Manager)
REFERENCES Salesreps(EmployeeNo)
Alter Table Offices
Add constraint fk_officesmanger
FOREIGN KEY (Manager)
REFERENCES Salesreps(EmployeeNo)
Alter Table Orders
Add constraint fk_customerno
FOREIGN KEY (CustomerNo)
REFERENCES Customers(CustomerNo),
constraint fk_salesrep
FOREIGN KEY (SalesRep)
REFERENCES Salesreps(EmployeeNo)
The table Products has a composite key (ManufactureID, ProductID), so you cannot uniquely identify a product by just the ProductId. Therefore you have to create a composite foreign key that references to both ManufactureId and ProductID:
Alter Table SalesDetail
Add FOREIGN KEY (ManufactureId, ProductID)
REFERENCES Products(ManufactureID, ProductID)
ProductID is not a primary key like the error says. In your code
PRIMARY KEY(ManufactureID, ProductID)
This creates a primary key that both of those columns combined.
The primary key for Products is (ManufactureID, ProductID). So the SalesDetail table should contain both these columns, and both should be part of the foreign key constraint:
Alter Table SalesDetail
Add FOREIGN KEY (ManufactureID, ProductID)
REFERENCES Products(ManufactureID, ProductID)

SQL Table Datastructure, is this wrong? Using CASCADING Delete

Here are the 3 tables I am having problems with:
Table: Opportunities - Holds various opportunity(job) descriptions
Table: Opportunities_Applicants - Holds various applicants applying for opportunities. 1 Applicant can only apply for 1 opportunity, however 1 opportunity can have many applicants
Table: Opportunities_Category - Holds category name and type. 1 Category can relate to many Opportunities.
I am trying to perform a CASCADING Delete when a Opportunity Category is deleted, it will delete corresponding Opportunities and Applicants for those Opportunities.
Is this structure appropriate or should I setup database differently? How should my table relationships be setup in order for the CASCADING Delete to work when a Opportunity Category is deleted?
Should I even be using CASCADING Delete?
create table Opportunities_Category
(
CategoryID int identity(1,1) not null
constraint PK_CategoryID primary key clustered,
[Name] varchar(150) not null,
[Type] varchar(100) not null --Pay, Volunteer, Volunteer Yearly
)
create table Opportunities
(
OpportunityID int identity(1,1) not null
constraint PK_OpportunityID primary key clustered,
CategoryID int not null
constraint FK_CategoryID foreign key references Opportunities_Category(CategoryID) ON DELETE CASCADE,
Title varchar(300) not null,
PostingDate datetime not null,
ClosingDate datetime not null,
Duration varchar(150) not null, --Part Time, Full Time, Seasonal, Contract
Compensation varchar(150) not null, --Hourly, Volunteer, Salary
[Description] varchar(5000) not null,
Qualifications varchar(5000) not null,
Show int not null
)
create table Opportunities_Applicant
(
ApplicantID int identity(1,1) not null
constraint PK_ApplicantID primary key clustered,
OpportunityID int not null
constraint FK_OpportunityID foreign key references Opportunities(OpportunityID) ON DELETE CASCADE,
[First] varchar(150) not null,
[Last] varchar(150) not null,
Phone varchar(20) not null,
Cell varchar(20) not null,
EMail varchar(200) not null,
CoverLetterResume varchar(300) null,
[Timestamp] datetime not null
)
It turns out that my tables are setup properly:
Yesterday, i had been trying to do: DELETE FROM Opportunities WHERE CategoryID = #CategoryID. This was only deleting the records from Opportunities and Opportunities_Applicants.
Today, i changed to: DELETE FROM Opportunities_Categoies WHERE CategoryID = #CategoryID and all 3 tables are deleting their corresponding records!
ALTER TABLE [dbo].[Opportunities] WITH CHECK ADD CONSTRAINT [FK_OpportunitiesCategory_Opportunities] FOREIGN KEY([CategoryID])
REFERENCES [dbo].[Opportunities_Category] ([CategoryID])
ON DELETE CASCADE
GO
Good Luck...