i have create a table and I need to add a database constraint "A customer with an age under 18 cannot rent a movie rated “18 or above”." How do I use SQL to add this in my table
You can use a trigger. When you want to enter information in the system to order a movie, do not allow the user to create a record if the age is less than the minimum required.
The following code snippet implements this scenario completely.
CREATE TABLE Customers
(
ID int identity,
FirstName nvarchar(100),
LastName nvarchar(100),
Age int,
primary key(ID))
CREATE TABLE Films
(
ID int identity,
FilmName nvarchar(100),
MinimumAge int,
primary key(ID))
CREATE TABLE OrderFilms
(
ID int identity,
CustomerID int,
FilmID int,
primary key(ID),
foreign key(CustomerID) references Customers,
foreign key(FilmID) references Films)
create trigger trigger_for_insert_into_OrderFilms
On OrderFilms
For Insert
AS
Declare #film int
Declare #customer int
Declare #filmage int
Declare #customerage int
set #film = (SELECT top 1 FilmID FROM inserted)
set #customer = (SELECT top 1 CustomerID FROM inserted)
set #filmage = (SELECT MinimumAge FROM Films WHERE ID = #film)
set #customerage = (SELECT Age FROM Customers WHERE ID = #customer)
IF(#filmage > 18 AND #customerage < 18)
BEGIN
PRINt 'ERROR, CUSTOMER AGE THE CUSTOMER IS YOUNG'
RollBack
END
Related
I'm trying to find out how can I extract the rows with the highest value on Suma column from a table which I did with this script:
SELECT specializare,
Count(codprocedura) AS NrProceduri,
Sum(pret) AS Suma
FROM (SELECT p.pret AS Pret,
fp.specializaredoctor AS Specializare,
fp.codprocedura AS CodProcedura
FROM proceduri p
INNER JOIN fisepacienti fp
ON fp.codpacienti = p.codproc)intermediar
GROUP BY intermediar.specializare
The DB tables can be created with this:
create table Pacienti(
CodP int not null primary key,
Nume varchar(50),
Prenume varchar(50),
Descriere varchar(50),
Varsta int,
DataNasterii varchar(50)
);
create table Proceduri(
CodProc int not null primary key,
Nume varchar(50),
Descriere varchar(50),
Pret int
);
create table FisePacienti(
PRIMARY KEY(CodPacienti, CodProcedura),
CodPacienti int FOREIGN KEY REFERENCES Pacienti(CodP),
CodProcedura int FOREIGN KEY REFERENCES Proceduri(CodProc),
Data varchar(50),
NumeDoctor varchar(50),
PrenumeDoctor varchar(50),
SpecializareDoctor varchar(50),
VechimeDoctor varchar(50)
);
You can use TOP (1) WITH TIES:
SELECT TOP (1) WITH TIES fp.specializare,
Count(fp.codprocedura) AS NrProceduri,
Sum(p.pret) AS Suma
FROM proceduri p JOIN
fisepacienti fp
ON fp.codpacienti = p.codproc
GROUP BY fp.specializare
ORDER BY SumA DESC;
Note that a subquery is not needed for the aggregation.
I have table :
Table Name : tbl_Income
EmployeeID Element FinancialYear Jan Feb Mar
00402060 Basic 2016-2017 100 200 300
00402060 HRA 2016-2017 100 200 300
00402060 DA 2016-2017 100 200 300
In which i want to fetch data from tbl_Income.
In which i fetch below problem.
Declare #Month varchar(10) = 'Jan'
select #Month from tbl_Income where EmployeeID = '00402060' and Element = 'Basic' and FinancialYear = '2016-2017'
I want to below Output
OUTPUT :
Jan
1 100
Please help me...
You can use Dynamic SQL like this:
declare #sql nvarchar(max)
Declare #Month varchar(10) = 'Jan'
declare #income int
set #sql = 'select #inc=' + #Month + ' from tbl_Income where EmployeeID = ''00402060'' and Element = ''Basic'' and FinancialYear = ''2016-2017'''
exec sp_executesql #sql, N'#inc int OUTPUT', #inc=#income OUTPUT
select #income as income
Beware though that this is open to SQL Injection attack.
You'd be better off fixing your design.
[Sample Database Design][1]
[1]: https://i.stack.imgur.com/2vxEb.png
-- table "dbo.Month"
CREATE TABLE dbo.Month (
Id int NOT NULL,
Name nvarchar(50) NOT NULL,
CONSTRAINT PK_Month PRIMARY KEY CLUSTERED (Id)
)
-- table IncomeType"
CREATE TABLE dbo.IncomeType (
Id int NOT NULL,
Name nvarchar(50) NOT NULL,
CONSTRAINT PK_IncomeType PRIMARY KEY CLUSTERED (Id)
)
-- table "FinancialYear"
CREATE TABLE dbo.FinancialYear (
Id int NOT NULL,
YearSpan nvarchar(50) NOT NULL,
CONSTRAINT PK_FinancialYear PRIMARY KEY CLUSTERED (Id)
)
-- table "Employee"
CREATE TABLE dbo.Employee (
Id int NOT NULL,
Name nvarchar(50) NOT NULL,
CONSTRAINT PK_Employee PRIMARY KEY CLUSTERED (Id)
)
-- table "Income"
CREATE TABLE dbo.Income (
Id int NOT NULL,
EmployeeId int NOT NULL,
TypeId int NOT NULL,
YearSpanId int NOT NULL,
MonthId int NOT NULL,
CONSTRAINT PK_Income PRIMARY KEY CLUSTERED (Id)
)
--Alter Each Table to add foreign key references
ALTER TABLE Income
ADD CONSTRAINT FK_Income_Employee FOREIGN KEY (EmployeeId) REFERENCES Employee (Id)
ALTER TABLE dbo.Income
ADD CONSTRAINT FK_Income_FinancialYear FOREIGN KEY (YearSpanId) REFERENCES dbo.FinancialYear (Id)
ALTER TABLE dbo.Income
ADD CONSTRAINT FK_Income_IncomeType FOREIGN KEY (TypeId) REFERENCES dbo.IncomeType (Id)
ALTER TABLE dbo.Income
ADD CONSTRAINT FK_Income_Month FOREIGN KEY (MonthId) REFERENCES dbo.Month (Id)
EmployeeID will come from the Employee table
Element will come from the income type table
FinancialYear --from the financial year table
MonthId from the months table
Now a simple join can help you get each value using the foreign key references
Declare #Month varchar(10) = 'Jan'
declare #v nvarchar(max)
declare #v1 INT
set #v =CONCAT('select #v1=' ,#month, ' from
table_a where EmployeeID = ''00402060'' and Element = ''Basic'' and FinancialYear = ''2016-2017''')
PRINT #V
EXECUTE sp_executesql #v,N'#V1 INT OUTPUT', #V1=#V1 OUTPUT;
SELECT #V1;
If exists data into parent table then update the child table on XML column based on the reference id, other wise insert into row.
CREATE TABLE Person
(
PersonId INT CONSTRAINT PK_Person_PersonId PRIMARY KEY,
Name VARCHAR(50),
SubMittedDate DATETIME,
SubmittedBy INT,
RejectedDate DATETIME,
RejectedBy INT
)
INSERT INTO Person VALUES(1, 'Sai', GETDATE(),1,null,null)
CREATE TABLE PersonXML
(
PersonXMLId INT IDENTITY(1,1) CONSTRAINT PK_PersonXML_PersonId PRIMARY KEY,
PersonId INT CONSTRAINT FK_PersonXML_Person FOREIGN KEY REFERENCES Person(PersonId),
Name VARCHAR(50),
PersonHistory XML
)
INSERT INTO PersonXML(PersonId,Name,PersonHistory )
SELECT PersonId
,Name
,(SELECT PersonId
,Name
,SubMittedDate
,SubmittedBy
,ISNULL(RejectedDate,0) AS RejectedDate
,ISNULL(RejectedBy, 0) AS RejectedBy
FROM Person FOR XML PATH('PersonHistory') )
FROM Person
SELECT * FROM Person
SELECT * FROM PersonXML
Whenever i Update Person Table in RejectedDate, RejectedBy Column then those changes has to reflect in PersonXML table on PersonHistory column automatically could anyone please find me way to achieve it.
UPDATE Person SET RejectedDate = GETDATE(), RejectedBy= 100 WHERE PersonId = 1
DECLARE #PersonId int,#RejectedDate datetime,#RejectedBy int
SET #PersonId=1
SET #RejectedDate=Getdate()+1
SET #RejectedBy=105
CREATE TABLE Person
(
PersonId INT CONSTRAINT PK_Person_PersonId PRIMARY KEY,
Name VARCHAR(50),
SubMittedDate DATETIME,
SubmittedBy INT,
RejectedDate DATETIME,
RejectedBy INT
)
INSERT INTO Person VALUES(1, 'Sai', GETDATE(),1,null,null)
CREATE TABLE PersonXML
(
PersonXMLId INT IDENTITY(1,1) CONSTRAINT PK_PersonXML_PersonId PRIMARY KEY,
PersonId INT CONSTRAINT FK_PersonXML_Person FOREIGN KEY REFERENCES Person(PersonId),
Name VARCHAR(50),
PersonHistory XML
)
INSERT INTO PersonXML(PersonId,Name,PersonHistory )
SELECT PersonId
,Name
,(SELECT PersonId
,Name
,SubMittedDate
,SubmittedBy
,ISNULL(RejectedDate,0) AS RejectedDate
,ISNULL(RejectedBy, 0) AS RejectedBy
FROM Person FOR XML PATH('PersonHistory') )
FROM Person
IF Exists(SELECT * FROM Person WHERE PersonId=#PersonId)
BEGIN
UPDATE Person
SET
RejectedDate =#RejectedDate ,RejectedBy=#RejectedBy
WHERE PersonId=#PersonId
UPDATE PersonXML
SET PersonHistory=
(SELECT PersonId
,Name
,SubMittedDate
,SubmittedBy
,ISNULL(RejectedDate,#RejectedDate) AS RejectedDate
,ISNULL(RejectedBy,#RejectedBy) AS RejectedBy
FROM Person FOR XML PATH('PersonHistory') )WHERE PersonId=#PersonId
END
ELSE
BEGIN
INSERT INTO Person
Select #PersonId,'', GETDATE(),1,#RejectedDate,#RejectedBy
END
SELECT * FROM Person
SELECT * FROM PersonXML
I've created three tables.
CREATE TABLE Clients
(
ClientID INT IDENTITY(1,1) PRIMARY KEY,
First_Name VARCHAR(50) NOT NULL,
Last_Name VARCHAR(50) NOT NULL,
)
CREATE TABLE Reservation
(
ReservationID INT IDENTITY(1,1) PRIMARY KEY,
ClientID INT FOREIGN KEY (ClientID) REFERENCES Clients(ClientID),
Reservation_paid VARCHAR(3) DEFAULT 'NO',
)
CREATE TABLE Payment
(
Payment_ID INT IDENTITY(1,1) PRIMARY KEY,
ClientID INT FOREIGN KEY (ClientID) REFERENCES Clients(ClientID),
ReservationID INT FOREIGN KEY (ReservationID) REFERENCES Reservation(ReservationID),
)
I would like to change the value of the column Reservation_paid to YES at the Reservation table whenever the Client does pay the reservation, and i want to do it automatically with trigger.
Example: If the ClientID at the Reservation table exists at the Payment table automatically the value of the Reservation_paid will set to YES.
Thank you in advance.
CREATE TRIGGER trgAfterInsert ON [dbo].[Payment]
FOR INSERT
AS
declare #ClientID int;
select #ClientID =i.ClientID from inserted i;
if update(ClientID)
UPDATE Reservation set Reservation_paid='Yes' WHERE
ClientID=#ClientID;
--PRINT 'AFTER INSERT trigger fired.'
After Insert Trigger should do something like this
UPDATE R
SET Reservation_paid = 'Yes'
FROM reservation R
WHERE EXISTS (SELECT 1
FROM INSERTED I
WHERE I.clientid = R.clientid
AND I.reservationid = R.reservationid)
CREATE TRIGGER trgAfterInsert ON [dbo].[Payment]
FOR INSERT
AS
declare #ClientID int;
select #ClientID =i.ClientID from inserted i;
insert into Reservation(ClientID,Reservation_paid)
values(#ClientID,'Yes');
--PRINT 'AFTER INSERT trigger fired.'
GO
Write a trigger that will work on table Reservation after any insert or update on ClientId column of table Payment. Then match the ClientID with ClientID column of Reservation table and update the corresponding Reservation_paid to YES.
Edit:
The trigger will be like this
CREATE TRIGGER `UpdateReservation_paid` AFTER INSERT OR UPDATE ON `Payment`
FOR EACH ROW BEGIN
AS
begin
update Reservation
SET Reservation_paid='YES'
Where NEW.ClientID = Reservation.ClientID
and NEW.ReservationID = Reservation.ReservationID
end
How to add values of primary key column into foreign key column of other table: I'm using SQL Server 2012
CREATE TABLE CUSTOMERS( ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL,
ADDRESS CHAR (25) , SALARY DECIMAL (18, 2), PRIMARY KEY (ID));
CREATE TABLE ORDERS ( ID INT NOT NULL, DATE DATETIME, CUSTOMER_ID INT references
CUSTOMERS(ID), AMOUNT VARCHAR (255), PRIMARY KEY (ID));
Here i need to take all values from primary key table 'customers' from column 'ID' to foreign key table orders to column 'ID'
DECLARE #A INT, #DATE DATETIME, #C_ID INT, #AMOUNTS INT;
SET #A =1;
SET #DATE ='2009-10-08 00:00:00';
SET #C_ID = 100
SET #AMOUNTS=1000;
WHILE #A <= 7
BEGIN
SET #DATE = DATEADD(DAY,1,#DATE);
SET #C_ID = #C_ID + 1
SET #AMOUNTS = #AMOUNTS+100;
INSERT INTO ORDERS(ID, DATE, CUSTOMER_ID,AMOUNT)
SELECT ID, #DATE, #C_ID, #AMOUNTS FROM CUSTOMERS WHERE AGE like'%';
SET #A = #A+1;
END
You have set your Orders table up with a Foreign Key on Customer_ID that references Customers(ID). So you can you only add rows to Orders if the ID exists in Customers. Right now you are trying to insert 101-107 in that column every time, so check if those IDs exists in Customers.
It seems to me that you SHOULD want to insert the Customers.ID column in Orders.Customer_ID, rather than Orders.ID. Is that what you meant?