How to model this many-many relation in Database? - sql-server

We have two tables ManagementPlan which tells what type of product model has to be used.Based on this model number, a particular product of that type is assigned to a patient during therapy session.How can we model the many-many relation between Product table and ManagementPlan table
MangamentPlan(
PlanID(PK),
DiagnosisID(FK),
PhysicianID(FK),
PMCModelID,
Objective,
Description,
DateTime
)
Product(
PMCProductID(PK),
ManuProductID(FK),
ManufacturerID(FK),
PMCModelID,
Manufacturer model,
Features description,
PurchaseDate,
Storage Location
)

Add a junction table:
ManagementPlanProduct(PlanID(PK, FK(ManagementPlan)), PMCProductID(PK, FK(Product)))

You need a junction table
ManagementPlanProduct (
PlanID (PK, FK)
PMCProductID (PK, FK)
)
CREATE TABLE ManagementPlanProduct (
PlanID int NOT NULL,
PMCProductID int NOT NULL,
CONSTRAINT PK_mpp PRIMARY KEY CLUSTERED (PlanID, PMCProductID)
);
ALTER TABLE ManagementPlanProduct
ADD CONSTRAINT FK_mpp_mp
FOREIGN KEY (PlanID) REFERENCES ManagementPlan (PlanID)
ON DELETE CASCADE;
ALTER TABLE ManagementPlanProduct
ADD CONSTRAINT FK_mpp_p
FOREIGN KEY (PMCProductID) REFERENCES Product (PMCProductID)
ON DELETE CASCADE;
You can also add other columns to the junction table like quantity, date added, sort order and so on.

Related

SQL Server why am I getting error for creating foreign key constraint for no matching key in referenced table?

I get this error from SQL Server:
Msg 1776, Level 16, State 0, Line 64
There are no primary or candidate keys in the referenced table 'Orders' that match the referencing column list in the foreign key 'FK_Cart_Orders'.
However, the OrderID column is in the Orders table, so I cannot understand why the error says there is no matching keys in the Orders table. I am obviously doing something wrong but do not know what it is.
My code is fairly short and is:
CREATE DATABASE TestMattressSite
GO
USE TestMattressSite
GO
CREATE TABLE Mattresses
(
MattressID INT IDENTITY NOT NULL,
)
GO
CREATE TABLE Customers
(
CustomerID INT IDENTITY NOT NULL,
)
GO
CREATE TABLE Orders
(
OrderID BIGINT IDENTITY NOT NULL,
CustomerID INT NOT NULL,
)
CREATE TABLE Cart
(
OrderID BIGINT NOT NULL,
MattressID INT NOT NULL,
CustomerID INT NOT NULL
)
GO
ALTER TABLE Mattresses
ADD CONSTRAINT PK_Mattresses PRIMARY KEY (MattressID)
GO
ALTER TABLE Customers
ADD CONSTRAINT PK_Customers PRIMARY KEY (CustomerID)
GO
ALTER TABLE Orders
ADD CONSTRAINT PK_Orders PRIMARY KEY (OrderID, CustomerID)
GO
ALTER TABLE Cart
ADD CONSTRAINT PK_Cart PRIMARY KEY (OrderID, MattressID)
GO
ALTER TABLE Orders
ADD CONSTRAINT FK_Orders_Customers
FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
GO
ALTER TABLE Cart
ADD CONSTRAINT FK_Cart_Mattresses
FOREIGN KEY (MattressID) REFERENCES Mattresses (MattressID),
CONSTRAINT FK_Cart_Orders
FOREIGN KEY (OrderID) REFERENCES Orders (OrderID),
CONSTRAINT FK_Cart_Customers
FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
GO
Can someone please take a look and point out my error?
Since your Orders table have primary key on two columns OrderID and CustomerID, its a composite primary key so when you want to reference this key as foreign key any table, you need to define all the column of composite primary key, like below.
ALTER TABLE Cart ADD
CONSTRAINT FK_Cart_Mattresses FOREIGN KEY (MattressID) REFERENCES Mattresses (MattressID),
CONSTRAINT FK_Cart_Orders FOREIGN KEY (OrderID, CustomerID) REFERENCES Orders (OrderID, CustomerID),
CONSTRAINT FK_Cart_Customers FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
GO
Or,
If you want your foreign key to have only one column OrderID, change your primary key like this:
ALTER TABLE Orders ADD
CONSTRAINT PK_Orders PRIMARY KEY (
OrderID
)
GO
With this, you current query will work as it is.
There already a question on this, refer this link.

Foreign Key Relationship with one of Multiple Tables

I have a language map table that each entry has the possibility of a foreign key relationship with a few different tables. What is the best schema to deal with this configuration?
Tables: LanguageMap, TableA, TableB
These are the two possibility:
1. Lookup Column Method - No Foreign Key Constraints:
Create Table LanguageMap (
Id int not null primary key,
Language nvarchar not null,
Value nvarchar not null,
Type nvarchar not null, -- 'TableA', 'TableB', etc.
ForeignTableId int not null -- Is Foreign key to another table dependent on the type of the row.
)
2. Multiple Foreign Key Columns
create Table LanguageMap(
Id int not null primary key,
Language nvarchar not null,
Value nvarchar not null,
Type nvarchar not null, -- 'Activity', 'Verb', etc.
TableAId int null,
TableBId int null
)
alter table LanguageMap add constraint FK_LanguageMap_TableA
foreign key (TableAId) references TableA (Id)
alter table LanguageMap add constraint FK_LanguageMap_TableA
foreign key (TableBId) references TableB (Id)
alter table LanguageMap add constraint CK_LanguageMap_OneIsNotNull
check (TableAId is not null or TableBId is not null)
go
alter table LanguageMap add constraint CK_LanguageMap_OneIsNull
check (TableAId is null or TableBId is null)
go
The foreign key constraints are based on Foreign Key for either-or column?
There is another alternative, called "Shared Primary Key". You can look this up. If TableA, TableB, TableC, etc. all "inherit" their PK as a copy of the PK from some Master table, called "TableMaster" for example, then you can just use that as an FK in LanguageMap.
The correct joins will select the correct instances.
The shared primary key is often used in conjunction with a design pattern called "Class Table Inheritance". Without knowing what TableA, TableB, TableC, etc. are about, I can't say whether Class Table Inheritance is relevant to your case.
In any event, look up both "Shared Primary Key" and "Class Table Inheritance" for further reading.
There are tags with those names in this area.

How to implement multiple inheritance in SQL?

In a relational database, if there is a Student table and Employee table, and a third table StudentAsst who indicates a multiple inheritance from both Student and Employee tables.
My Question: in SQL how to create the StudentAsst, and what is its primary key?
Since a StudentAsst is-a Student and is-an Employee, your table could have a primary key consisting of EmployeeID and StudentID:
CREATE TABLE StudentAsst
(StudentID int,
EmployeeID int,
...,
CONSTRAINT PK_StudentAsst PRIMARY KEY (StudentID, EmployeeID),
CONSTRAINT FK_Employee FOREIGN KEY (EmployeeId)
REFERENCES Employee(EmployeeID),
CONSTRAINT FK_Student FOREIGN KEY (StudentID)
REFERENCES Student(StudentID)
)
Here is an example of a similar situation with Student, Teachers and Parents.

Delete query in sqlite for child tables

I have 3 tables, like Employee, Department and Electronics tables.
Electronics table is child table for Department table and Department table is child table for Employee table.
I want to delete one record in Employee table where E_id=2 ( this is Primary key) this is Foreign key in Department table (E_id is Foreign key and Dept_id is Primary key) and Dept_id is Foreign Key in Electronics table.
First I want to delete related records in Electronics table then Department table and finally Employee table.
Please guide me how to do it.
You can read more about foreign key support in sqlite here: http://www.sqlite.org/foreignkeys.html
but you should be able to turn it on:
sqlite> PRAGMA foreign_keys = ON;
and then setup the database schema with the deletes cascading:
-- Database schema
CREATE TABLE Employee(
E_id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE Department(
Dept_id INTEGER PRIMARY KEY,
name TEXT,
E_id INTEGER REFERENCES Employee(E_id) ON DELETE CASCADE
);
CREATE TABLE Electronics(
Elec_id INTEGER PRIMARY KEY,
name TEXT,
Dept_id INTEGER REFERENCES Department(Dept_id) ON DELETE CASCADE
);
With all this in place and the data in the tables:
DELETE FROM Employee WHERE E_id = 2;

Add a unique constraint of a sql table as foreign key reference to an another sql table

how to add a unique constraint of a sql table as foreign key reference to an another sql table in sql server 2005
In order to add FK constraint (in child table to parent table) you have to add unique constraint to parent table columns of relationship.
All the rest is optional or has nothing to do with FK:
no obligatory need of any primary key
no need of uniqueness in child table colums(s)
The parent table (in such FK relation) is frequently called (including by SSMS) as Primary Key table but PK is not must, unique key/constraint in parent table is enough (as PK is unique, it is particular case of unique constraint in parent table).
Drop TableA and TableB from answer by Matt, which is confusing for beginners,
and recreate them as
CREATE TABLE parentB--TableB
(
PK1 INT NOT NULL,
PK2 INT NOT NULL,
--I would not have additional non-referenced data in parent table,
--rather in child table
--SomeData VARCHAR(1000),
--CONSTRAINT PK_TableB PRIMARY KEY CLUSTERED (PK1, PK2)
)
CREATE TABLE childA--TableA
(
--PK INT, -- NOT NULL,
FK1 INT-- NOT NULL, -- Or NULL, if you''d rather.
FK2 INT --NOT NULL --,
, SomeData VARCHAR(1000)
--CONSTRAINT PK_TableA PRIMARY KEY CLUSTERED (PK),
--CONSTRAINT FK_TableA_FK1FK2 FOREIGN KEY (FK1, FK2) REFERENCES TableB (PK1, PK2),
--CONSTRAINT Cons2cols UNIQUE(FK1, FK2)
)
Now, in order, to add FK
ALTER TABLE childA
ADD
--constraint FK1_childA
--this is optional, if one needs to add his own custom name
FOREIGN KEY (FK1) REFERENCES parentB(PK1);
you should first create unique constraint on corresponding referenced column in parent table column:
ALTER TABLE parentB ADD
--CONSTRAINT YourUniqueName --uncomment for adding your own name to constraint
UNIQUE(PK1)
Similarly for 2 columns foreign key constraint
(first, you need corresponding unique constraint in parent table):
ALTER TABLE parentB ADD
--CONSTRAINT YourUniqueName --for adding your own name to unique constraint
UNIQUE(PK1,PK2)
ALTER TABLE childA
ADD
--constraint yourUniqueName --uncomment for adding your own name to FK constraint
FOREIGN KEY (FK1, FK2) REFERENCES parentB(PK1, PK2);
Apologies but I'm not really sure what you're asking here. Giving more of an example with table definitions would help! I think you're saying you have two columns in TableA in a unique constraint named "Cons2cols", and you also want these two columns to be a FK to a two column PK / unqiue pair in TableB.
That works as follows, if you're creating the tables from scratch:
CREATE TABLE TableB (
PK1 INT NOT NULL,
PK2 INT NOT NULL,
SomeData VARCHAR(1000),
CONSTRAINT PK_TableB PRIMARY KEY CLUSTERED (PK1, PK2)
)
CREATE TABLE TableA (
PK INT NOT NULL,
FK1 INT NOT NULL, -- Or NULL, if you''d rather.
FK2 INT NOT NULL,
CONSTRAINT PK_TableA PRIMARY KEY CLUSTERED (PK),
CONSTRAINT FK_TableA_FK1FK2 FOREIGN KEY (FK1, FK2) REFERENCES TableB (PK1, PK2),
CONSTRAINT Cons2cols UNIQUE(FK1, FK2)
)
If the tables already exist, you can add in these same constraints after the fact:
ALTER TABLE TableA ADD CONSTRAINT FK_TableA_FK1FK2 FOREIGN KEY (FK1, FK2) REFERENCES TableB (PK1, PK2);
ALTER TABLE TableA ADD CONSTRAINT Cons2cols UNIQUE(FK1, FK2);
Either way, TableA now has a unique, 2 column FK to another table.
You need to keep in mind that adding a FK on a column does not automatically put an index on that column. You'll need to do this in two steps.
1) Make a column in your table a FK to a parent table.
2) Add a unique constraint on that same column
Forget about the unique constraint for now. Just create your new foreign key on the two columns.
ALTER TABLE dbo.PurchaseDetail
ADD FOREIGN KEY (Customer, Product)
REFERENCES dbo.Purchase (Customer, Product)
I prefer this approach where this table references another table (transaction_log):
CREATE TABLE transaction_settings_log
(
transaction_fk UUID NOT NULL
CONSTRAINT transaction_log_pkey REFERENCES transaction_log (id) UNIQUE,
group_selected BOOLEAN DEFAULT TRUE,
leg_closed BOOLEAN DEFAULT FALSE
);

Resources