0% found this document useful (0 votes)
15 views19 pages

SQL

Uploaded by

Study Forest
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views19 pages

SQL

Uploaded by

Study Forest
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 19

--DROP TABLE WALLET_LANDLORD

CREATE TABLE WALLET_LANDLORD


(
ID_w NVARCHAR(10) PRIMARY KEY,
Balance MONEY
)
-----

--DROP TABLE LANDLORD

CREATE TABLE LANDLORD


(
ID_l NVARCHAR(10) PRIMARY KEY,
Name NVARCHAR(50) NOT NULL,
PhoneNumber NVARCHAR(10) NOT NULL,
Birthday DATE NOT NULL,
ID_w NVARCHAR(10) NOT NULL,

FOREIGN KEY (ID_w) REFERENCES dbo.WALLET_LANDLORD(ID_w),

CONSTRAINT LL_CheckAge CHECK (DATEDIFF(year, Birthday, GETDATE()) >= 18),


CONSTRAINT LL_CheckPhoneNumber CHECK (PhoneNumber LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
);

---------

--DROP TABLE LOGIN_ACCOUNT

CREATE TABLE LOGIN_ACCOUNT (


ID_l NVARCHAR(10) ,
UserName NVARCHAR(255) PRIMARY KEY,
Password NVARCHAR(255) NOT NULL,

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


);
---------

--DROP TABLE TENANT

CREATE TABLE TENANT (


ID_t NVARCHAR(10) PRIMARY KEY,
Name NVARCHAR(50) NOT NULL,
PhoneNumber NVARCHAR(10) NOT NULL,
Job NVARCHAR(50),
Birthday DATE,
Balance MONEY NOT NULL,
ID_l NVARCHAR(10) NULL,

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


CONSTRAINT TN_CheckAge CHECK (DATEDIFF(year, Birthday, GETDATE()) >= 18),
CONSTRAINT TN_CheckPhoneNumber CHECK (PhoneNumber LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
);
---------

--DROP TABLE BROKERAGECOMPANY

CREATE TABLE BROKERAGECOMPANY (


TaxCode NVARCHAR(10) PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
Address NVARCHAR(100) NOT NULL,
Wallet MONEY NOT NULL,
BonusPrice MONEY NOT NULL,
PriceperMonth MONEY NOT NULL,

);
---------

--DROP TABLE ROOM

CREATE TABLE ROOM (


RoomNumber NVARCHAR(10) PRIMARY KEY,
Area INT NOT NULL,
Interior INT NOT NULL,
State BIT NOT NULL,
PriceperMonth MONEY,
ElectricityPrice MONEY NOT NULL,
WaterPrice MONEY NOT NULL,
ID_l NVARCHAR(10),

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


);
---------

--DROP TABLE HIRED

CREATE TABLE HIRED (


ID_l NVARCHAR(10),
TaxCode NVARCHAR(10),
DayEnd DATE NOT NULL,
DayStart DATE NOT NULL,

CONSTRAINT Check_DayStartEnd_HIRED CHECK (DayEnd > DayStart),

PRIMARY KEY (ID_l,TaxCode),


FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),
FOREIGN KEY (TaxCode) REFERENCES dbo.BROKERAGECOMPANY(TaxCode)
);
---------

--DROP TABLE RENT

CREATE TABLE RENT (


ID_t NVARCHAR(10),
RoomNumber NVARCHAR(10),
TaxCode NVARCHAR(10) NULL,
DayEnd DATE NOT NULL,
DayStart DATE NOT NULL,

CONSTRAINT Check_DayStartEnd_RENT CHECK ( DayEnd > DayStart),

PRIMARY KEY (ID_t,RoomNumber),


FOREIGN KEY (ID_t) REFERENCES dbo.TENANT(ID_t),
FOREIGN KEY (TaxCode) REFERENCES dbo.BROKERAGECOMPANY(TaxCode),
FOREIGN KEY (RoomNumber) REFERENCES dbo.ROOM(RoomNumber)
);
---------

--DROP TABLE CONTRACT

CREATE TABLE CONTRACT (


Code NVARCHAR(10) PRIMARY KEY,
DayStart DATE,
Price MONEY,
Period INT,
RoomNumber NVARCHAR(10) NOT NULL,
ID_t NVARCHAR(10) NOT NULL,

FOREIGN KEY (RoomNumber) REFERENCES dbo.ROOM(RoomNumber),


FOREIGN KEY (ID_t) REFERENCES dbo.TENANT(ID_t)
);

CREATE TABLE BILL (


Code NVARCHAR(10) PRIMARY KEY,
Price MONEY,
ElectricNumber FLOAT NOT NULL,
WaterNumber FLOAT NOT NULL,
Day DATE NULL,
ID_l NVARCHAR(10) NOT NULL,
RoomNumber NVARCHAR(10) NOT NULL,
ID_t NVARCHAR(10) NOT NULL,

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


FOREIGN KEY (RoomNumber) REFERENCES dbo.ROOM(RoomNumber),
FOREIGN KEY (ID_t) REFERENCES dbo.TENANT(ID_t)
);

--------------

----3.1 Quản lý ví tiền chung của Landlord


--insert
GO
CREATE PROCEDURE InsertWalletLandlord
@ID_w NVARCHAR(10),
@Balance MONEY
AS
BEGIN
BEGIN TRY
INSERT INTO WALLET_LANDLORD (ID_w, Balance)
VALUES (@ID_w, @Balance)

PRINT 'Đã thêm Wallet Landlord thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateWalletLandlord
@ID_w NVARCHAR(10),
@Balance MONEY
AS
BEGIN
BEGIN TRY
UPDATE WALLET_LANDLORD
SET Balance = @Balance
WHERE ID_w = @ID_w

PRINT 'Đã cập nhật Wallet Landlord thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteWalletLandlord
@ID_w NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM WALLET_LANDLORD
WHERE ID_w = @ID_w

PRINT 'Đã xóa Wallet Landlord thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

--------------3.1 Quản lý Tenant


--insert
GO
CREATE PROCEDURE InsertTenant
@ID_t NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Job NVARCHAR(50),
@Birthday DATE,
@Balance MONEY
AS
BEGIN
BEGIN TRY
-- Insert data
INSERT INTO TENANT (ID_t, Name, PhoneNumber, Job, Birthday, Balance)
VALUES (@ID_t, @Name, @PhoneNumber, @Job, @Birthday, @Balance)

PRINT 'Tenant inserted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateTenant
@ID_t NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Job NVARCHAR(50),
@Birthday DATE,
@Balance MONEY
AS
BEGIN
BEGIN TRY
-- Update data
UPDATE TENANT
SET Name = @Name,
PhoneNumber = @PhoneNumber,
Job = @Job,
Birthday = @Birthday,
Balance = @Balance
WHERE ID_t = @ID_t

PRINT 'Tenant updated successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteTenant
@ID_t NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Delete data
DELETE FROM TENANT
WHERE ID_t = @ID_t

PRINT 'Tenant deleted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--Tìm kiếm dựa vào ID_t
GO
CREATE FUNCTION FindTenantByID
(
@ID_t NVARCHAR(10)
)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM TENANT
WHERE ID_t = @ID_t
);
--trigger bắt lỗi khi insert/update/delete
GO
CREATE TRIGGER CheckTenant
ON TENANT
FOR INSERT, UPDATE, DELETE
AS
BEGIN
-- Kiểm tra tên của Tenant không được để trống
IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(Name) = '' OR Name IS NULL)
BEGIN
DECLARE @errMsg nvarchar(50)
SELECT @errMsg = N'Lỗi: Tên của Tenant không được để trống.'
RAISERROR(@errMsg, 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Tenant không được để trống


IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(PhoneNumber) = '' OR PhoneNumber IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Tenant không được để trống.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Tenant đã tồn tại (trong trường hợp INSERT hoặc UPDATE)
IF EXISTS (SELECT 1 FROM TENANT t INNER JOIN inserted i ON t.PhoneNumber = i.PhoneNumber WHERE i.ID_t IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Tenant đã tồn tại.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Tenant không được để trống (khi UPDATE)


IF EXISTS (SELECT 1 FROM inserted WHERE ID_t IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Tenant để chỉnh sửa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Tenant không được để trống (khi DELETE)


IF EXISTS (SELECT 1 FROM deleted WHERE ID_t IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Tenant để xóa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
END

--------------------3.2 Quản lý Landlord


GO
CREATE PROCEDURE InsertLandlord
@ID_l NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Birthday DATE,
@ID_w NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Insert data
INSERT INTO LANDLORD (ID_l, Name, PhoneNumber, Birthday, ID_w)
VALUES (@ID_l, @Name, @PhoneNumber, @Birthday, @ID_w)

PRINT 'Landlord inserted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
GO
CREATE PROCEDURE UpdateLandlord
@ID_l NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Birthday DATE,
@ID_w NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Update data
UPDATE LANDLORD
SET Name = @Name,
PhoneNumber = @PhoneNumber,
Birthday = @Birthday
WHERE ID_l = @ID_l

PRINT 'Landlord updated successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteLandlord
@ID_l NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Delete data
DELETE FROM LANDLORD
WHERE ID_l = @ID_l

PRINT 'Landlord deleted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;

--Tìm kiếm dựa vào ID_l


GO
CREATE FUNCTION FindLandlordByID
(
@ID_l NVARCHAR(10)
)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM LANDLORD
WHERE ID_l = @ID_l
);
--trigger kiểm tra insert/update/delete
GO
CREATE TRIGGER CheckLandlord
ON LANDLORD
FOR INSERT, UPDATE, DELETE
AS
BEGIN
DECLARE @ID_l NVARCHAR(10), @UserName NVARCHAR(255), @Password NVARCHAR(255)

SELECT @ID_l = ID_l, @UserName = 'Landlord_' + ID_l, @Password = 'password' + ID_l -- Mặc định password là 'password'
FROM inserted

-- Thêm tài khoản đăng nhập vào bảng LOGIN_ACCOUNT


INSERT INTO LOGIN_ACCOUNT (ID_l, UserName, Password)
VALUES (@ID_l, @UserName, @Password)

-- Kiểm tra tên của Landlord không được để trống


IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(Name) = '' OR Name IS NULL)
BEGIN
DECLARE @errMsg nvarchar(50)
SELECT @errMsg = N'Lỗi: Tên của Landlord không được để trống.'
RAISERROR(@errMsg, 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Landlord không được để trống


IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(PhoneNumber) = '' OR PhoneNumber IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Landlord không được để trống.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Landlord đã tồn tại (trong trường hợp INSERT hoặc UPDATE)
IF EXISTS (SELECT 1 FROM LANDLORD l INNER JOIN inserted i ON l.PhoneNumber = i.PhoneNumber WHERE i.ID_l IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Landlord đã tồn tại.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Landlord không được để trống (khi UPDATE)


IF EXISTS (SELECT 1 FROM inserted WHERE ID_l IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Landlord để chỉnh sửa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Landlord không được để trống (khi DELETE)


IF EXISTS (SELECT 1 FROM deleted WHERE ID_l IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Landlord để xóa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
END

--3.3 Quản lý company


--insert
GO
CREATE PROCEDURE InsertCompany
@TaxCode NVARCHAR(10),
@Name NVARCHAR(100),
@Address NVARCHAR(100),
@Wallet MONEY,
@BonusPrice MONEY,
@PriceperMonth MONEY
AS
BEGIN
BEGIN TRY
INSERT INTO BROKERAGECOMPANY (TaxCode, Name, Address, Wallet, BonusPrice, PriceperMonth)
VALUES (@TaxCode, @Name, @Address, @Wallet, @BonusPrice, @PriceperMonth)

PRINT 'Company inserted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateCompany
@TaxCode NVARCHAR(10),
@Name NVARCHAR(100),
@Address NVARCHAR(100),
@Wallet MONEY,
@BonusPrice MONEY,
@PriceperMonth MONEY
AS
BEGIN
BEGIN TRY
UPDATE BROKERAGECOMPANY
SET Name = @Name,
Address = @Address,
Wallet = @Wallet,
BonusPrice = @BonusPrice,
PriceperMonth = @PriceperMonth
WHERE TaxCode = @TaxCode

PRINT 'Company updated successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteCompany
@TaxCode NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM BROKERAGECOMPANY
WHERE TaxCode = @TaxCode

PRINT 'Company deleted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;

--3.3 Quản lý Room


--proc insert
GO
CREATE PROCEDURE InsertRoom
@RoomNumber NVARCHAR(10),
@Area INT,
@Interior INT,
@State BIT,
@ElectricityPrice MONEY,
@WaterPrice MONEY,
@ID_l NVARCHAR(10)
AS
BEGIN
DECLARE @PriceperMonth MONEY

-- Tính giá mới


SET @PriceperMonth = 1000000 + @Area * 50000 + @Interior * 50000
BEGIN TRY
INSERT INTO ROOM (RoomNumber, Area, Interior, State, PriceperMonth, ElectricityPrice, WaterPrice, ID_l)
VALUES (@RoomNumber, @Area, @Interior, @State, @PriceperMonth, @ElectricityPrice, @WaterPrice, @ID_l)
PRINT 'Phòng được thêm thành công.'
END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateRoom
@RoomNumber NVARCHAR(10),
@Area INT,
@Interior INT,
@State BIT,
@ElectricityPrice MONEY,
@WaterPrice MONEY,
@ID_l NVARCHAR(10)
AS
BEGIN
-- Khai báo biến để lưu giá trị mới của PriceperMonth
DECLARE @NewPriceperMonth MONEY

-- Tính toán giá trị mới cho PriceperMonth


SET @NewPriceperMonth = 1000000 + @Area * 50000 + @Interior * 50000

BEGIN TRY
-- Cập nhật thông tin của phòng
UPDATE ROOM
SET Area = @Area,
Interior = @Interior,
State = @State,
ElectricityPrice = @ElectricityPrice,
WaterPrice = @WaterPrice,
PriceperMonth = @NewPriceperMonth,
ID_l = @ID_l
WHERE RoomNumber = @RoomNumber;

PRINT 'Thông tin phòng đã được cập nhật thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteRoom
@RoomNumber NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM ROOM
WHERE RoomNumber = @RoomNumber

PRINT 'Phòng đã được xóa thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--3.6 function
-- Hàm tính tháng dựa vào daystart và dayend
GO
CREATE FUNCTION dbo.CalculateMonth (@DayStart DATE, @DayEnd DATE)
RETURNS MONEY
AS
BEGIN
DECLARE @Month INT
SET @Month =
CASE WHEN (day(@DayStart) = day(@DayEnd)) THEN (DATEDIFF(month, @DayStart, @DayEnd))
WHEN (day(@DayStart) < day(@DayEnd)) THEN (DATEDIFF(month, @DayStart, @DayEnd) + 1)
ELSE DATEDIFF(month, @DayStart, @DayEnd)
END
RETURN @Month
END;

-- hàm tính Tiền dựa vào giá tiền hằng tháng và số tháng
GO
CREATE FUNCTION dbo.CalculatePrice (@PriceperMonth MONEY, @Month INT)
RETURNS MONEY
AS
BEGIN
DECLARE @Price MONEY
SET @Price = @Month * @PriceperMonth
RETURN @Price
END;

-- 3. Quản lý hợp đồng


GO
CREATE TRIGGER CalculateContractPriceAndPeriod
ON CONTRACT
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @ID_t NVARCHAR(10), @RoomNumber NVARCHAR(10), @Period INT, @Price MONEY, @DayStart DATE

-- Lấy ID_t, RoomNumber, và DayStart từ bảng RENT


SELECT @ID_t = i.ID_t, @RoomNumber = i.RoomNumber, @DayStart = i.DayStart
FROM inserted i

--Số tháng hợp đồng thuê


SELECT @Period = dbo.CalculateMonth(re.DayStart, re.DayEnd)
FROM RENT re
WHERE re.ID_t = @ID_t

-- Tính giá cho hợp đồng bằng cách sử dụng hàm CalculatePrice (= tiền hằng tháng * số tháng thuê)
-- Tiền phòng hằng tháng (PriceperMonth) được tính dựa trên thông tin của ROOM đó
-- Thời gian thuê (số tháng thuê) được tính dựa trên ngày bắt đầu&ngày kết thúc từ bảng RENT
SELECT @Price = dbo.CalculatePrice(r.PriceperMonth, dbo.CalculateMonth(re.DayStart, re.DayEnd))
FROM ROOM r
INNER JOIN RENT re ON r.RoomNumber = re.RoomNumber
WHERE re.ID_t = @ID_t

-- Cập nhật giá và thời gian thuê trong bảng CONTRACT


UPDATE CONTRACT
SET Price = @Price,
Period = @Period
WHERE ID_t = @ID_t AND RoomNumber = @RoomNumber

--Cập nhật trạng thái của Phòng thành đã có người thuê (State -> 1)
UPDATE ROOM
SET State = 1
WHERE RoomNumber = @RoomNumber
END;
--proc delêt contract
GO
CREATE PROCEDURE DeleteContract
@Code NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM CONTRACT
WHERE Code = @Code;

PRINT 'Hợp đồng đã được xoá thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

-- Trigger xóa contract -> xóa rent

GO
CREATE TRIGGER DeleteRentOnContractDelete
ON CONTRACT
AFTER DELETE
AS
BEGIN
DECLARE @DeletedContracts TABLE (Code NVARCHAR(10))

-- Lưu các hợp đồng bị xóa vào bảng tạm


INSERT INTO @DeletedContracts (Code)
SELECT Code FROM deleted

-- Xóa các bản ghi trong bảng RENT tương ứng với các hợp đồng bị xóa
DELETE FROM RENT
WHERE CONCAT(ID_t, RoomNumber) IN (SELECT Code FROM @DeletedContracts)

-- Cập nhật trạng thái của Room về false (0)


UPDATE ROOM
SET State = 0
WHERE RoomNumber IN (SELECT RoomNumber FROM deleted)
END;

--3.7 Quản lý Landlord thuê Company


--proc insert Hired
GO
CREATE PROCEDURE InsertHired
@ID_l NVARCHAR(10),
@TaxCode NVARCHAR(10),
@DayStart DATE,
@DayEnd DATE
AS
BEGIN
-- Kiểm tra xem thông tin thuê công ty môi giới đã tồn tại hay chưa
IF EXISTS (SELECT 1 FROM HIRED WHERE ID_l = @ID_l AND TaxCode = @TaxCode)
BEGIN
-- Nếu đã tồn tại, phát sinh lỗi và thông báo
RAISERROR(N'Thông tin thuê công ty môi giới đã tồn tại.', 16, 1);
RETURN; -- Kết thúc stored procedure
END

BEGIN TRY
-- Chèn thông tin thuê công ty môi giới vào bảng HIRED
INSERT INTO HIRED (ID_l, TaxCode, DayStart, DayEnd)
VALUES (@ID_l, @TaxCode, @DayStart, @DayEnd);

PRINT 'Thông tin thuê công ty môi giới đã được thêm thành công.'
END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

--trigger HIRED: Landlord trả tiền thuê cho COMPANY


GO
--DROP TRIGGER InsertHired
GO
CREATE TRIGGER TriggerInsertHired
ON HIRED
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @TaxCode NVARCHAR(10), @ID_l NVARCHAR(10), @Price MONEY

-- Lấy thông tin CompanyID và LandlordID từ bảng HIRED


SELECT @TaxCode = i.TaxCode, @ID_l = i.ID_l
FROM inserted i

-- Tính giá thuê dựa trên thông tin từ bảng BROKERAGECOMPANY, sử dụng hàm CalculatePrice (= tiền hằng tháng * số tháng
thuê)
-- Tiền Chủ thuê Công ty hằng tháng (PriceperMonth) được tính dựa trên Giá tiền Hằng thánng Công ty đó quy định
(BROKERAGECOMPANY.PriceperMonth)
-- Thời gian thuê (số tháng thuê) được tính dựa trên ngày bắt đầu&ngày kết thúc khi nhập HIRED
SELECT @Price = dbo.CalculatePrice(c.PriceperMonth, dbo.CalculateMonth(i.DayStart, i.DayEnd))
FROM BROKERAGECOMPANY c, inserted i

IF @Price > (SELECT Balance FROM WALLET_LANDLORD)


-- Trừ giá thuê từ tài khoản của chủ nhà (Landlord)
BEGIN
-- Nếu không đủ tiền thuê, phát sinh lỗi và thông báo
RAISERROR(N'Người chủ không đủ tiền để thuê Công ty môi giới!', 16, 1);
ROLLBACK TRANSACTION;
RETURN; -- Kết thúc trigger
END
ELSE
BEGIN
BEGIN TRANSACTION; -- Bắt đầu giao dịch
BEGIN TRY
UPDATE WALLET_LANDLORD
SET Balance = Balance - (@Price)

UPDATE BROKERAGECOMPANY
SET Wallet = Wallet + (@Price)

COMMIT TRANSACTION; -- Chấp nhận giao dịch


END TRY
BEGIN CATCH
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch nếu có lỗi
END CATCH
END
END;

--3.8 Quản lý Tenant thuê Room


--proc insert Rent
GO
CREATE PROCEDURE InsertRent
@ID_t NVARCHAR(10),
@RoomNumber NVARCHAR(10),
@DayStart DATE,
@DayEnd DATE,
@TaxCode NVARCHAR(10) = NULL -- Tham số TaxCode mặc định là NULL
AS
BEGIN
-- Kiểm tra xem phòng đã được thuê hay chưa
IF EXISTS (SELECT 1 FROM RENT WHERE RoomNumber = @RoomNumber AND DayEnd >= @DayStart)
BEGIN
-- Nếu phòng đã được thuê, phát sinh lỗi và thông báo
RAISERROR(N'Phòng đã được thuê trong thời gian này.', 16, 1);
RETURN; -- Kết thúc stored procedure
END

BEGIN TRY
-- Chèn thông tin thuê phòng vào bảng RENT
INSERT INTO RENT (ID_t, RoomNumber, TaxCode, DayStart, DayEnd)
VALUES (@ID_t, @RoomNumber, @TaxCode, @DayStart, @DayEnd);

PRINT 'Thông tin thuê phòng đã được thêm thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

--trigger RENT, Code = "Roomnumber" + "Id_t", và check state của room phải = 0,
--kiểm tra Balance trong Tenant nếu đủ tiền thuê trọ thì được thuê (rent) --> Tạo Contract
--kiểm tra nếu Tenant có thuê Company thì WALLET_LANDLORD trừ tiền BonusPrice (Company)
GO
--DROP TRIGGER TriggerInsertRent
GO
CREATE TRIGGER TriggerInsertRent
ON RENT
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @ID_t NVARCHAR(10), @RoomNumber NVARCHAR(10), @Price MONEY, @TaxCode NVARCHAR(10), @DayStart DATE

-- Lấy thông tin ID_t, RoomNumber, TaxCode, DayStart từ bảng RENT


SELECT @ID_t = i.ID_t, @RoomNumber = i.RoomNumber, @TaxCode = i.TaxCode, @DayStart = i.DayStart
FROM inserted i

-- Kiểm tra trạng thái của phòng, trống thì được thuê (State = 0)
IF (SELECT State FROM ROOM WHERE RoomNumber = @RoomNumber) = 1
BEGIN
-- Nếu trạng thái của phòng là 0 (đã có người thuê, State = 0), phát sinh lỗi và thông báo
RAISERROR(N'Phòng đã được thuê. Vui lòng tìm phòng khác !', 16, 1);
ROLLBACK TRANSACTION;
RETURN; -- Kết thúc trigger
END

-- Kiểm tra xem ROOM có được thuê bởi một Company có TaxCode trùng khớp với TaxCode trong Rent không
IF @TaxCode IS NOT NULL
BEGIN
IF NOT EXISTS (
SELECT 1
FROM ROOM r
INNER JOIN HIRED h ON r.ID_l = h.ID_l
WHERE r.RoomNumber = @RoomNumber AND h.TaxCode = @TaxCode
)
BEGIN
-- Nếu không trùng, phát sinh lỗi và hủy bỏ giao dịch
RAISERROR(N'Phòng không thuộc sở hữu của Công ty môi giới này!', 16, 1);
ROLLBACK TRANSACTION;
RETURN;
END
END

-- Tính giá thuê dựa trên thông tin từ bảng ROOM, sử dụng hàm CalculatePrice (= tiền hằng tháng * số tháng thuê)
-- Tiền phòng hằng tháng (PriceperMonth) được tính dựa trên thông tin của ROOM đó
-- Thời gian thuê (số tháng thuê) được tính dựa trên ngày bắt đầu&ngày kết thúc khi nhập RENT
SELECT @Price = dbo.CalculatePrice(r.PriceperMonth, dbo.CalculateMonth(i.DayStart, i.DayEnd))
FROM ROOM r, inserted i
WHERE (r.RoomNumber = @RoomNumber)

IF @Price > (SELECT Balance FROM TENANT WHERE ID_t = @ID_t)


BEGIN
-- Nếu không đủ tiền thuê, phát sinh lỗi và thông báo
RAISERROR(N'Người thuê không đủ tiền để thuê phòng này!', 16, 1);
ROLLBACK TRANSACTION;
RETURN; -- Kết thúc trigger
END
ELSE
BEGIN TRANSACTION; -- Bắt đầu giao dịch
BEGIN TRY
-- Thêm hợp đồng vào bảng CONTRACT (Code = "ID_t"+"RoomNumber")
INSERT INTO CONTRACT (Code, DayStart, RoomNumber, ID_t)
VALUES ((CONCAT(@ID_t, @RoomNumber)), @DayStart, @RoomNumber, @ID_t);

UPDATE TENANT
SET ID_l = r.ID_l
FROM ROOM r
WHERE @ID_t = ID_t AND @RoomNumber = RoomNumber

IF @TaxCode IS NOT NULL


BEGIN
-- Kiểm tra xem TaxCode của Rent có trùng với TaxCode của Company mà Landlord thuê không
IF EXISTS (
SELECT 1
FROM HIRED h
INNER JOIN BROKERAGECOMPANY c ON h.TaxCode = c.TaxCode
WHERE h.TaxCode = @TaxCode
)
BEGIN
-- Nếu trùng, cập nhật WALLET_LANDLORD
UPDATE WALLET_LANDLORD
SET Balance = Balance - (SELECT BonusPrice FROM BROKERAGECOMPANY WHERE TaxCode = @TaxCode)

UPDATE BROKERAGECOMPANY
SET Wallet = Wallet + BonusPrice
WHERE TaxCode = @TaxCode

END
ELSE
BEGIN
--Nếu không trùng, phát sinh lỗi và hủy bỏ giao dịch
ROLLBACK TRANSACTION;
RETURN;
END
END

COMMIT TRANSACTION; -- Chấp nhận giao dịch


END TRY
BEGIN CATCH
RAISERROR(N'Lỗi!!!!!!!!!!!!!!!!!!!!!!!!!', 16, 1);
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch nếu có lỗi
END CATCH

END;

-----3.4 Quản lý hoá đơn (bill)


--insert
GO
CREATE PROCEDURE InsertBill
@Code NVARCHAR(10),
@ElectricNumber FLOAT,
@WaterNumber FLOAT,
@Day DATE,
@ID_l NVARCHAR(10),
@RoomNumber NVARCHAR(10),
@ID_t NVARCHAR(10)
AS
BEGIN
BEGIN TRY
INSERT INTO BILL (Code, ElectricNumber, WaterNumber, Day, ID_l, RoomNumber, ID_t)
VALUES (@Code, @ElectricNumber, @WaterNumber, @Day, @ID_l, @RoomNumber, @ID_t)

PRINT 'Đã thêm Bill thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateBill
@Code NVARCHAR(10),
@ElectricNumber FLOAT,
@WaterNumber FLOAT,
@Day DATE
AS
BEGIN
DECLARE @Price MONEY

-- Tính giá trị mới cho thuộc tính Price dựa trên các thuộc tính khác
SELECT @Price = ROOM.PriceperMonth + @ElectricNumber * ROOM.ElectricityPrice + @WaterNumber * ROOM.WaterPrice
FROM ROOM
INNER JOIN BILL ON ROOM.RoomNumber = BILL.RoomNumber
WHERE BILL.Code = @Code

-- Cập nhật giá trị mới cho thuộc tính Price


UPDATE BILL
SET Price = @Price,
ElectricNumber = @ElectricNumber,
WaterNumber = @WaterNumber
WHERE Code = @Code
END;
--delete
GO
CREATE PROCEDURE DeleteBill
@Code NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM BILL
WHERE Code = @Code

PRINT 'Đã xóa Bill thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--proc tìm kiếm bill
GO
CREATE PROCEDURE FindBillByCode
@Code NVARCHAR(10)
AS
BEGIN
-- Kiểm tra xem hóa đơn có tồn tại không
IF EXISTS (SELECT * FROM BILL WHERE Code = @Code)
BEGIN
-- Nếu tồn tại, trả về thông tin của hóa đơn
SELECT *
FROM BILL
WHERE Code = @Code
END
ELSE
BEGIN
-- Nếu không tồn tại, thông báo rằng không tìm thấy hóa đơn
PRINT 'Không tìm thấy hóa đơn với mã ' + @Code
END
END;
--trigger
GO
CREATE TRIGGER TriggerInsertBill
ON BILL
AFTER INSERT
AS
BEGIN
DECLARE @Code NVARCHAR(10), @Price MONEY, @ElectricNumber FLOAT, @WaterNumber FLOAT, @Day DATE,
@RoomNumber NVARCHAR(10), @ID_t NVARCHAR(10), @DayStartContract DATE

-- Lấy thông tin từ bảng BILL


SELECT @Code = i.Code, @ElectricNumber = i.ElectricNumber, @WaterNumber = i.WaterNumber,
@Day = i.Day, @RoomNumber = i.RoomNumber, @ID_t = i.ID_t
FROM inserted i

-- Lấy ngày bắt đầu của hợp đồng từ bảng CONTRACT


SELECT @DayStartContract = DayStart
FROM CONTRACT
WHERE RoomNumber = @RoomNumber AND ID_t = @ID_t

-- Kiểm tra nếu ngày của BILL nằm trong 10 ngày sau khi bắt đầu hợp đồng
IF (@Day >= @DayStartContract)
BEGIN
-- Tính giá 1 tháng BILL
SELECT @Price = PriceperMonth + @ElectricNumber * ElectricityPrice + @WaterNumber * WaterPrice
FROM ROOM
WHERE RoomNumber = @RoomNumber

BEGIN TRANSACTION; -- Bắt đầu giao dịch


BEGIN TRY
-- Trừ tiền từ tài khoản của Tenant
UPDATE TENANT
SET Balance = Balance - @Price
WHERE ID_t = @ID_t

-- Cộng tiền vào tài khoản của Landlord


UPDATE WALLET_LANDLORD
SET Balance = Balance + @Price

-- Cập nhật giá vào bảng BILL


UPDATE BILL
SET Price = @Price
WHERE Code = @Code

COMMIT TRANSACTION; -- Chấp nhận giao dịch


END TRY
BEGIN CATCH
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch nếu có lỗi
END CATCH
END
ELSE
BEGIN
-- Nếu ngày của BILL không nằm trong 10 ngày sau khi bắt đầu hợp đồng, xoá hợp đồng
DELETE FROM CONTRACT
WHERE RoomNumber = @RoomNumber AND ID_t = @ID_t
-- Xoá bản ghi trong bảng RENT tương ứng với hợp đồng bị xoá
DELETE FROM RENT
WHERE ID_t = @ID_t AND RoomNumber = @RoomNumber
-- Huỷ việc chèn dữ liệu vào bảng BILL
RAISERROR(N'Ngày của BILL không nằm trong 10 ngày sau khi bắt đầu hợp đồng, xoá hợp đồng!', 16, 1);
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch
END
END;

GO
--EXEC
EXEC InsertWalletLandlord 'WL1', 1000000000;

GO
EXEC InsertTenant 'TN1', 'John Doe', '1234567890', 'Engineer', '1990-01-01', 50000000;
GO
EXEC InsertLandlord 'LL1', 'Alice Smith', '9876543210', '1970-01-01', 'WL1';
GO
EXEC InsertRoom 'R1', 40, 2, 0, 5000, 5000, 'LL1';
GO
EXEC InsertCompany 'C1', 'Company1', 'VVN', 100000000, 1000000, 500000;
GO
-- Chủ thuê Công Ty môi giới 3 tháng
EXEC InsertHired 'LL1', 'C1', '2024-04-01', '2024-06-13';
GO
--Người thuê thuê phòng 2 tháng
EXEC InsertRent 'TN1', 'R1', '2024-04-01', '2024-06-01', 'C1' ;
GO
--Bill lần 1
EXEC InsertBill 'B1_1', 5, 5, '2024-04-06', 'LL1', 'R1', 'TN1';
--Bill lần 2
EXEC InsertBill 'B1_2', 5, 5, '2024-04-06', 'LL1', 'R1', 'TN1';

--EXEC2
GO
EXEC InsertTenant 'TN2', 'Tom', '2234567890', 'Engineer', '1990-01-01', 50000000;
GO
EXEC InsertLandlord 'LL2', 'Alice Smith', '9876543210', '1970-01-01', 'WL1';
GO
EXEC InsertRoom 'R2', 50, 5, 0, 5000, 5000, 'LL2';
GO
EXEC InsertCompany 'C2', 'Company2', 'VVN', 100000000, 1000000, 500000;
GO
-- Chủ thuê Công Ty môi giới 2 tháng
EXEC InsertHired 'LL2', 'C2', '2024-07-01', '2024-09-01';
GO
--Người thuê thuê phòng 3 tháng
EXEC InsertRent 'TN2', 'R2', '2024-07-01', '2024-10-01' ;
GO
--Bill lần 1
EXEC InsertBill 'B2_1', 11, 11, '2024-07-06', 'LL2', 'R2', 'TN2';

You might also like