Tải bản đầy đủ (.doc) (25 trang)

Đề cương bài tập CƠ SỞ DỮ LIỆU SQL

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (198.9 KB, 25 trang )

TÀI LIỆU CƠ SỞ DỮ LIỆU SQL
I.Tạo bảng và thiết lập mối quan hệ giữa các bảng.
CREATE TABLE CTDONDH
(Sohd char(4) not null,
MaVTu Char(4) not Null,
Constraint K1
Primary Key (Sohd,MaVTu)
)
CREATE TABLE DONDH
( SoHD char (4) not null primarykey,
NgayDH datetime,
MaNhaCC char(3) Not Null,
Foreign key (MANHACC) References NHACC(MaNhaCC)
)
ALTER TABLE DONDH
ADD
CONSTRAINT fk_dondh_nhaCC
FOREIGN KEY (MaNHacc)
REFERENCE NHACC(MANHACC)
ON DELETE CASCADE ON UPDATE CASCADE
II. Tạo các truy vấn sau:
1. Viết câu lệnh để giảm 15% đơn giá nhập cho các mặt hàng nhập vào
ngày thứ tư
UPDATE CTPNHAP
SET DGNhap=DGNhap-DGNhap*15/100
FROM PNHAP INNER JOIN CTPNHAP ON
PNHAP.SoPN=CTPNHAP.SoPN
WHERE NgayNhap IN (SELECT NgayNhap
FROM PNHAP
WHERE DATENAME(DW,NgayNhap)='Wednesday')
1




2. Viết câu lệnh để xóa đi các đơn đặt hàng vào thứ hai , của những nhà
cung cấp ở TP.HCM
DELETE
FROM DONDH
WHERE NgayDH IN (SELECT NgayDH
FROM DONDH INNER JOIN NHACC ON
DONDH.MaNhaCC=NHACC.MaNhaCC
WHERE DATENAME(DW, NgayDH)='Monday' AND
DiaChi LIKE '%HCM%')
3. Cho biết danh sách các đơn đặt hàng chưa từng được nhập hàng
SELECT *
FROM DONDH
WHERE SoDH NOT IN ( SELECT SoDH
FROM PNHAP)
4. Cho biết danh sách các mặt hàng chưa bao giờ được đặt hàng
SELECT *
FROM VATTU
WHERE MaVTu NOT IN (SELECT MaVTu
FROM CTDONDH)
5. Cho biết nhà cung cấp nào có nhiều đơn đặt hàng nhất
SELECT TOP 1 WITH TIES MaNhaCC, COUNT(*) AS TongSoDONDH
FROM DONDH
GROUP BY MaNhaCC
ORDER BY TongSoDONDH DESC
6. Cho biết vật tư nào có tổng số lượng xuất bán là lớn nhất
SELECT TOP 1 WITH TIES MaVTu, SUM(SLXuat) AS TongSLXuat
2



FROM CTPXUAT
GROUP BY MaVTu
ORDER BY TongSLXuat DESC
7. Cho biết đơn đặt hàng nào có nhiều mặt hàng nhất
SELECT TOP 1 WITH TIES SoDH, COUNT(*) AS SoMatHang
FROM CTDONDH
GROUP BY SoDH
ORDER BY SoMatHang DESC
8. Hiển thị các thông tin trong bảng CTPXUAT và bổ sung thêm cột
thành tiền, sao cho có thống kê dòng tổng cộng số tiền ở từng phiếu
xuất.
SELECT * ,(SLXuat*DGXuat) AS ThanhTien
FROM CTPXUAT
ORDER BY SoPX
COMPUTE SUM(SLXuat*DGXuat) BY SoPX
9. Hiển thị các thông tin : mã vật tư , số nhập hàng, số lượng nhập, đơn
giá nhập trong bảng CTPNHAP và thống kê dòng tổng cộng số lượng ,
giá thấp nhất, giá cao nhất ở từng vật tư.
SELECT MaVTu, SoPN, SLNhap, DGNhap
FROM CTPNHAP
ORDER BY MaVTu
COMPUTE SUM(SLNhap),MIN(DGNhap), MAX(DGNhap) BY MaVTu

III. Sử dụng cú pháp IF, WHILE và CASE lồng vào
các lệnh truy vấn cần thiết trong các yêu cầu sau:
1. Cho biết đơn giá xuất trung bình của hàng hóa “Đầu DVD Hitachi 1
đĩa” trong bảng CTPXUAT hiện giờ là bao nhiêu? Nếu lớn hơn
3.800.000 thì in ra “không nên thay đổi giá bán”, ngược lại in ra “đã
đến lúc tăng giá bán”

- CÁCH 1:
3


DECLARE @DGTB REAL
SELECT @DGTB = AVG(DGXuat)
FROM CTPXUAT
WHERE MaVTu IN (SELECT MaVTu
FROM VATTU
WHERE TenVTu = 'Đầu DVD Hitachi 1 đĩa')
IF @DGTB > 3800000
PRINT N'Không nên thay đổi giá bán'
ELSE
PRINT N'Đã đến lúc tăng giá bán
- CÁCH 2:
IF(SELECT AVG(DGXuat) FROM CTPXUAT WHERE MaVTu IN
(SELECT MaVTu FROM VATTU WHERE TenVTu = 'Đầu DVD Hitachi 1
đĩa'))>3800000
PRINT N'Không nên thay đổi giá bán'
ELSE
PRINT N'Đã đến lúc tăng giá bán'
2. Sử dụng hàm DATENAME để tính xem có đơn đặt hàng nào đã
được lập vào ngày chủ nhật không?Nếu có thì in ra danh sách các
đơn đặt hàng đó, ngược lại thì in ra chuỗi ‘Ngày lập các đơn hàng
đều là hợp lệ’.
DECLARE @DEM INT
SELECT @DEM=COUNT(*)
FROM DONDH
WHERE DATENAME(DW, NgayDH)='Sunday'
IF @DEM > 0

SELECT * FROM DONDH WHERE DATENAME(DW,
NgayDH)='Sunday'
ELSE
PRINT N'Ngày lập các đơn hàng đều là hợp lệ'
4


3. Hãy cho biết đã có bao nhiêu phiếu nhập hàng cho đơn đặt hàng
D001, nếu có thì in ra ‘Có xx số phiếu nhập hàng cho đơn đặt hàng
D001’, ngược lại thì in ra ‘Chưa có nhập hàng nào cho D001’.
DECLARE @DEM INT
SELECT @DEM = COUNT (*)
FROM PNHAP
WHERE SoDH = 'D001'
IF @DEM > 0
PRINT N'Có' + CAST (@DEM AS CHAR(3)) + N'số phiếu nhập hàng
cho đơn đặt hàng D001'
ELSE
PRINT N'Chưa có nhập hàng nào cho D001'
4. Tạo một bảng tên VATTU_Temp có cấu trúc và dữ liệu dựa vào
bảng VATTU (chỉ lấy 2 cột MaVTu, TenVTu). Sau đó sử dụng vòng
lặp WHILE viết đoạn chương trình dùng để xóa từng dòng dữ liệu
trong bảng VATTU_Temp với điều kiện câu lệnh bên trong vòng lặp
khi mỗi lần thực hiện chỉ được phép xóa một dòng dữ liệu trong
bảng VATTU_Temp. Trong khi xóa nên thông báo ra màn hình nội
dung ‘Đã xóa vật tư’ + Tên vật tư.
SELECT MaVTu, TenVTu INTO VATTU_Temp
FROM VATTU
SET NOCOUNT ON
DECLARE @MaVTu CHAR(4), @TenVTu VARCHAR(100)

WHILE EXISTS ( SELECT * FROM VATTU_Temp)
BEGIN
SELECT TOP 1 @MaVTu=MaVTu, @TenVTu=TenVTu FROM
VATTU_Temp
DELETE VATTU_Temp WHERE @MaVTu=MaVTu
PRINT N'Đã xóa vật tư' + @TenVTu
END
SET NOCOUNT OFF
5. Liệt kê danh sách các đơn đặt hàng trong bảng DONDH, bổ sung
thêm cột hiển thị thứ trong tuần (bằng tiếng việt) của ngày đặt hàng.
5


SELECT *, Thứ_Tiếng_Việt = CASE DATENAME(DW,NgayDH)
WHEN 'Sunday' THEN N'Chủ Nhật'
WHEN 'Monday' THEN N'Thứ Hai'
WHEN 'Tuesday' THEN N'Thứ Ba'
WHEN 'Wednesday' THEN N'Thứ Tư'
WHEN 'Thursday' THEN N'Thứ Năm'
WHEN 'Friday' THEN N'Thứ Sáu'
WHEN 'Saturday' THEN N'Thứ Bảy' END
FROM DONDH
6. Giảm đơn giá xuất của các hàng hóa bán ra trong tháng 01/2007
theo các quy tắc sau:
- Không giảm nếu số lượng < 4
- Giảm 5 % nếu số lượng >= 4 và số lượng < 10
- Giảm 10 % nếu số lượng > = 10 và số lượng < = 20
- Giảm 20 % nếu số lượng > 20
UPDATE CTPXUAT
SET DGXuat = CASE

WHEN SLXuat < 4 THEN DGXuat
WHEN SLXuat >= 4 AND SLXuat < 10 THEN DGXuat - DGXuat *
5/100
WHEN SLXuat >= 10 AND SLXuat <= 20 THEN DGXuat - DGXuat *
10/100
WHEN SLXuat > 20 THEN DGXuat - DGXuat * 20/100 END
WHERE SoPX IN (SELECT SoPX FROM PXUAT WHERE
MONTH(NgayXuat)='01' AND YEAR(NgayXuat)='2007')

6


IV. Tạo các VIEW sau:
1. Tạo view có tên vw_DONDH_TongSLNhap bao gồm các thông tin
sau: số đặt hàng, tổng số lượng nhập. View này được dùng để thống
kê tổng số lượng nhập theo đơn hàng.
CREATE VIEW vw_DONDH_TongSLNhap
AS
SELECT DONDH.SoDH, SUM(CTPNHAP.SLNhap) AS TongSLNhap
FROM PNHAP RIGHT JOIN DONDH ON
PNHAP.SoDH=DONDH.SoDH LEFT JOIN CTPNHAP ON
PNHAP.SoPN= CTPNHAP.SoPN
GROUP BY DONDH.SoDH
GO
2. Tạo view có tên vw_DONDH_TongSLDatNhap bao gồm các thông
tin: số đặt hàng, tổng số lượng đặt, tổng số lượng nhập. View này
dùng để thống kê những đơn đặt hàng nào đã được nhập hàng đầy
đủ.

CREATE VIEW vw_DONDH_TongSLDatNhap

AS
SELECT DONDH.SoDH, SUM (CTDONDH.SLDat) AS TongSLDat,
SUM (CTPNHAP.SLNhap) AS TongSLNhap
FROM CTDONDH LEFT JOIN DONDH ON CTDONDH.SoDH =
DONDH.SoDH
LEFT JOIN PNHAP ON CTDONDH.SoDH = PNHAP.SoDH
LEFT JOIN CTPNHAP ON PNHAP.SoPN = CTPNHAP.SoPN
AND CTDONDH.MaVTu = dbo.CTPNHAP.MaVTu
GROUP BY DONDH.SoDH
GO
7


3. Tạo view có tên vw_DONDH_DaNhapDu bao gồm các thông tin: số
đặt hàng, thông báo. Trong đó cột thông báo có 2 giá trị là “Đã nhập
đủ” nếu đơn đặt hàng đó đã nhập đủ hoặc “Chưa nhập đủ” nếu đơn
đặt hàng đó chưa nhập đủ.
CREATE VIEW vw_DONDH_DaNhapDu
AS
SELECT CTDONDH.SoDH, CASE WHEN SUM(CTPNHAP.SLNhap)
>= SUM(CTDONDH.SLDat) THEN N'Đã nhập đủ' ELSE N'Chưa nhập đủ'
END AS DaNhapDu
FROM CTDONDH LEFT JOIN
DONDH ON CTDONDH.SoDH = DONDH.SoDH LEFT
JOIN
PNHAP ON CTDONDH.SoDH = PNHAP.SoDH LEFT JOIN
CTPNHAP ON CTDONDH.MaVTu = CTPNHAP.MaVTu
AND PNHAP.SoPN = CTPNHAP.SoPN
GROUP BY CTDONDH.SoDH
GO

4. Tạo view có tên vw_TongNhap bao gồm các thông tin: năm tháng,
mã vật tư, tổng số lượng nhập. View này dùng để thống kê số lượng
nhập của các vật tư trong từng năm tháng tương ứng ( năm tháng
có dạng YYYY-MM). Chú ý: không sử dụng bảng tồn kho.
CREATER VIEW ww_TongNhap ()
AS
Select Right(convert(char(10),pnhap.Ngaynhap,103),7),
MaVTu,Sum(SLNhap) From Pnhap,CTPNhap
Where Pnhap.Sopn=CTPNhap.Sopn
Group by right(convert(char(10),Pnhap.Ngaynhap,103),7),
CTPNhap.MaVTu
GO

8


5. Tạo view có tên vw_TongXuat bao gồm các thông tin: năm tháng,
mã vật tư, tổng số lượng xuất. View này dùng để thống kê số lượng
xuất của các vật tư trong từng năm tháng tương ứng ( năm tháng có
dạng YYYY-MM). Chú ý: không sử dụng bảng tồn kho.
CREATER VIEW ww_TongXuat ()
AS
Select Right(convert(char(10),Pxuat.NgayXuat,103),7),
MaVTu,Sum(CTPXuat.SLXuat) From Pxuat,CTPXuat Where
Pnhap.Sopn=CTPNhap.Sopn
Group by right(convert(char(10),Pnhap.Ngaynhap,103),7),
CTPNhap.MaVTu
GO
6. Tạo view bao gồm các thông tin: số đơn hàng, Ngày đặt hàng, Tổng
số lượng đặt . View này dùng để thống kê tổng số lượng đặt hàng

theo từng số đơn hàng trong tháng 1 năm 2007.
CREATE VIEW vw_DONDH_TongSLDat
AS
SELECT DONDH.SoDH, NgayDH, SUM(SLDat)AS TongSLDat
FROM DONDH INNER JOIN CTDONDH ON
DONDH.SoDH=CTDONDH.SoDH
WHERE CONVERT(CHAR(6),NgayDH,112)='200701'
GROUP BY DONDH.SoDH, NgayDH
GO

7. Tạo view bao gồm các thông tin sau: Số phiếu nhập, Ngày nhập,
Tổng số lượng nhập. View này dùng để thống kê tổng số lượng nhập
hàng theo từng số phiếu trong năm ngoái.
CREATE VIEW vw_PNHAP_TongSLNhap
AS
9


SELECT PNHAP.SoPN, NgayNhap, SUM(SLNhap) AS TongSLNhap
FROM PNHAP INNER JOIN CTPNHAP ON
PNHAP.SoPN=CTPNHAP.SoPN
WHERE CONVERT(CHAR(4),NgayNhap,112)='2011'
GROUP BY PNHAP.SoPN, NgayNhap
GO

10


V. Tạo các thủ tục lưu trữ ( Stored Procedure ) sau:
1. Xây dựng thủ tục tính số lượng đặt hàng với tên

spud_DONDH_TinhSLDat gồm có 2 tham số vào là : Số đặt hàng và mã
vật tư, 1 tham số ra là : Số lượng đặt hàng của một vật tư theo một số đặt
hàng.
CREATE PROCEDURE spud_DONDH_TinhSLDat @SoDH
CHAR(4),@MaVTu CHAR(4), @SLDat INT OUTPUT
AS
DECLARE @KQ INT
SELECT @KQ = SLDat
FROM CTDONDH
WHERE SoDH=@SoDH AND MaVTu=@MaVTu
SET @SLDat= @KQ
GO
2. Xây dựng thủ tục tính tổng số lượng đã nhập hàng với tên
spud_PNHAP_TinhTongSLNHang gồm 2 tham số vào là : Số đặt hàng
và mã vật tư, 1 tham số ra là: Tổng số lượng đã nhập hàng của một vật tư
theo một số đặt hàng.
CREATE PROCEDURE spud_PNHAP_TinhTongSLNHang @SoDH
CHAR(4), @MaVTu CHAR(4), @TongSLNhap INT OUTPUT
AS
DECLARE @KQ INT
SELECT @KQ= SUM(SLNhap)FROM CTPNHAP INNER JOIN
PNHAP ON CTPNHAP.SoPN=PNHAP.SoPN
WHERE SoDH=@SoDH AND MaVTu=@MaVTu
SET @TongSLNhap = ISNULL(@KQ,0)
GO

11


3. Xây dựng thủ tục thêm mới dữ liệu vào bảng VATTU với tên

spud_VATTU_Them gồm có 4 tham số vào chính là giá trị thêm mới cho
các cột trong bảng VATTU: mã vật tư, tên vật tư, đơn vị tính, phần trăm.
Trong đó cần kiểm tra các ràng buộc dữ liệu phải hợp lệ trước khi thực
hiện lệnh INSERT INTO để thêm dữ liệu vào các bảng VATTU: Mã vật
tư phải chưa có trong bảng VATTU.
CREATE PROCEDURE spud_VATTU_Them @MaVTu CHAR(4),
@TenVTu VARCHAR(100), @DVTinh VARCHAR(50),@PhanTram REAL
AS
IF EXISTS (SELECT * FROM VATTU WHERE MaVTu=@MaVTu)
BEGIN
PRINT N'Mã vật tư này đã có => Không thêm được'
RETURN
END
INSERT INTO VATTU VALUES (@MaVTu, @TenVTu, @DVTinh,
@PhanTram)
GO
4. Xây dựng thủ tục xóa một vật tư có trong bảng VATTU với tên
spud_VATTU_Xoa gồm có một tham số vào chính là mã vật tư cần xóa.
Trong đó cần kiểm tra ràng buộc dữ liệu trước khi thực hiện lệnh
DELETE để xóa dữ liệu trong bảng VATTU:
- Mã vật tư phải chưa có trong bảng CTDONDH
- Mã vật tư phải chưa có trong bảng CTPNHAP
- Mã vật tư phải chưa có trong bảng CTPXUAT
- Mã vật tư phải chưa có trong bảng TONKHO
CREATE PROCEDURE spud_VATTU_Xoa @MaVTu CHAR(4)
AS
IF EXISTS ( SELECT * FROM CTDONDH WHERE
MaVTu=@MaVTu)
BEGIN
PRINT N'Mã vật tư này đã có trong bảng CTDONDH =>

Không xóa được'
12


RETURN
END
IF EXISTS ( SELECT * FROM CTPNHAP WHERE
MaVTu=@MaVTu)
BEGIN
PRINT N'Mã vật tư này đã có trong bảng CTPNHAP =>
Không xóa được'
RETURN
END
IF EXISTS ( SELECT * FROM CTPXUAT WHERE
MaVTu=@MaVTu)
BEGIN
PRINT N'Mã vật tư này đã có trong bảng CTPXUAT =>
Không xóa được'
RETURN
END
IF EXISTS ( SELECT * FROM TONKHO WHERE MaVTu=@MaVTu)
BEGIN
PRINT N'Mã vật tư này đã có trong bảng TONKHO =>
Không xóa được'
RETURN
END
DELETE VATTU WHERE MaVTu=@MaVTu
GO
5. Xây dựng thủ tuc sửa đổi vật tư trong bảng VATTU với tên
supd_VATTU_Sua gồm có 4 tham số vào chính là giá trị cần thay đổi của

các cột trong bảng VATTU ( trừ cột mã vật tư): mã vật tư , tên vật tư, đơn
vị tính và phần trăm. Trong thủ tục chỉ cần thực hiện lệnh UPDATE SET
để cập nhật dữ liệu vào bảng VATTU với các giá trị tương ứng.
13


CREATE PROCEDURE supd_VATTU_Sua @MaVTu CHAR(4), @TenVTu
VARCHAR(100)=NULL, @DVTinh VARCHAR(50)=NULL,@PhanTram
REAL=NULL
AS
IF NOT EXISTS (SELECT * FROM VATTU WHERE MaVTu=
@MaVTu)
BEGIN
PRINT N'Mã vật tư không tồn tại ==> Không sửa được'
RETURN
END
UPDATE VATTU SET TenVTu = ISNULL (@TenVTu, TenVTu),
DVTinh = ISNULL (@DVTinh, DVTinh),
PhanTram = ISNULL (@PhanTram, PhanTram)
WHERE MaVTu= @MaVTu
GO
6. Xây dựng thủ tục liệt kê các cột dữ liệu trong bảng TONKHO có thể
thêm cột TenVTu trong bảng VATTU với tên
spud_TONKHO_BCaoTonKho gồm có một tham số vào là : Năm tháng
muốn lọc dữ liệu.
CREATE PROCEDURE spud_TONKHO_BCaoTonKho @NamThang
CHAR(6)
AS
SELECT a.MaVTu,TenVTu, NamThang , SLDau, TongSLN, TongSLX,
SLCuoi

FROM TONKHO a INNER JOIN VATTU b ON a.MaVTu=b.MaVTu
WHERE NamThang= @NamThang
GO
7. Xây dựng thủ tục liệt kê các cột dữ liệu trong 2 bảng dữ liệu PXUAT
và CTPXUAT có thể hiện thêm cột TenVTu trong bảng VATTU với tên là
spud_PXUAT_BCaoPXuat gồm có một tham số vào là : Số phiếu xuất
muốn lọc dữ liệu có giá trị mặc định là NULL. Tuy nhiên nếu lúc gọi
thực hiện thủ tục mà không truyền giá trị số phiếu xuất vào thì xem như
14


không lọc gì cả, khi đó thủ tục sẽ liệt kê tất cả các phiếu xuất đang có
trong bảng PXUAT.
CREATE PROCEDURE spud_PXUAT_BCaoPXuat @SoPX CHAR(4) =
NULL
AS
IF @SoPX IS NULL
SELECT a.SoPX,a.MaVTu,TenVTu,SLXuat,DGXuat,NgayXuat,
TenKH
FROM CTPXUAT a INNER JOIN VATTU b ON
a.MaVTu=b.MaVTu INNER JOIN PXUAT c ON a.SoPX=c.SoPX
ELSE
SELECT a.SoPX,a.MaVTu,TenVTu,SLXuat,DGXuat,NgayXuat,
TenKH
FROM CTPXUAT a INNER JOIN VATTU b ON
a.MaVTu=b.MaVTu INNER JOIN PXUAT c ON a.SoPX=c.SoPX
WHERE a.SoPX=@SoPX
GO
8. Xây dựng thủ tục để tính tổng giá trị hàng xuất với 2 tham số vào là
tháng và năm, 1 tham số ra là tổng giá trị hàng xuất của tháng và

năm đó.
CREATE PROCEDURE spud_PXUAT_TongDGXuat @ThangXuat
CHAR(2), @NamXuat CHAR(4), @TongDGXuat MONEY OUTPUT
AS
DECLARE @KQ MONEY
SELECT @KQ=SUM(DGXuat)
FROM CTPXUAT INNER JOIN PXUAT ON
CTPXUAT.SoPX=PXUAT.SoPX
WHERE MONTH(NgayXuat)=@ThangXuat AND
YEAR(NgayXuat)=@NamXuat
SET @TongDGXuat = ISNULL(@KQ,0)
GO

15


9. Tạo thủ tục thêm mới dữ liệu vào bảng PNHAP . Trong đó cần kiểm
tra dữ liệu hợp lệ trước khi thêm:
- Số phiếu nhập phải là duy nhất
- Số đơn hàng phải có trong bảng DONDH
CREATE PROCEDURE spud_PNHAP_Them @SoPN
CHAR(4),@NgayNhap DATETIME , @SoDH CHAR(4)
AS
IF EXISTS (SELECT * FROM PNHAP WHERE SoPN=@SoPN)
BEGIN
PRINT N'Số phiếu nhập đã tồn tại ==> Không thể thêm
được'
RETURN
END
IF NOT EXISTS (SELECT * FROM DONDH WHERE

SoDH=@SoDH)
BEGIN
PRINT N'Số đơn hàng không có trong bảng DONDH ==>
Không thể thêm được'
RETURN
END
INSERT INTO PNHAP VALUES (@SoPN,@NgayNhap,@SoDH)
GO

16


VI. Tạo các hàm (Function) sau:
1. Fn_TongNhapThang(@NamThang, @MaVTu) trả về tổng số lượng
đã nhập trong tháng của vật tư. Chú ý: @NamThang có dạng
YYYYMM.
CREATE FUNCTION Fn_TongNhapThang (@NamThang CHAR(6),
@MaVTu CHAR(4)) RETURNS INT
BEGIN
DECLARE @KQ INT
SELECT @KQ= SUM(SLNhap)
FROM CTPNHAP INNER JOIN PNHAP ON
CTPNHAP.SoPN=PNHAP.SoPN
WHERE MaVTu=@MaVTu AND
CONVERT(CHAR(6),NgayNhap,112)=@NamThang
RETURN ISNULL(@KQ,0)
END
2. Fn_TongXuatThang (@NamThang, @MaVTu) trả về tổng số lượng
đã xuất trong tháng của vật tư.
CREATE FUNCTION Fn_TongXuatThang (@NamThang CHAR(6),

@MaVTu CHAR(4)) RETURNS INT
BEGIN
DECLARE @KQ INT
SELECT @KQ=SUM (SLXuat)
FROM CTPXUAT INNER JOIN PXUAT ON
CTPXUAT.SoPX=PXUAT.SoPX
WHERE MaVTu=@MaVTu AND
CONVERT(CHAR(6),NgayXuat,112)=@NamThang
RETURN ISNULL(@KQ,0)
END
17


3. Fn_TongNhap (@SoDH, @MaVTu) trả về tổng số lượng đã nhập
của vật tư theo số đặt hàng
CREATE FUNCTION Fn_TongNhap ( @SoDH CHAR(4), @MaVTu
CHAR(4)) RETURNS INT
BEGIN
DECLARE @Tong INT
SELECT @Tong=SUM(SLNhap)
FROM PNHAP a INNER JOIN CTPNHAP b ON a.SoPN=b.SoPN
WHERE SoDH=@SoDH AND MaVTu=@MaVTu
RETURN ISNULL(@Tong,0)
END
4. Sử dụng hàm Fn_TongNhap đã tạo để viết hàm Fn_ConNhap
(@SoDH, @MaVTu) trả về số lượng còn phải nhập của mã vật tư
theo số đặt hàng

CREATE FUNCTION Fn_ConNhap ( @SoDH CHAR(4), @MaVTu
CHAR(4)) RETURNS INT

BEGIN
DECLARE @KQ INT
SELECT @KQ= SUM(SLDat) - DBO.Fn_TongNhap (@SoDH,
@MaVTu)
FROM CTDONDH
WHERE SoDH=@SoDH AND MaVTu=@MaVTu
RETURN ISNULL(@KQ,0)
END
5. Fn_TonCuoi (@MaVTu, @NamThang)trả về số lượng tồn cuối kỳ
của vật tư theo năm tháng.
CREATE FUNCTION Fn_TonCuoi (@MaVTu CHAR(4), @NamThang
CHAR(6)) RETURNS INT
18


BEGIN
DECLARE @KQ INT
SELECT @KQ = SLCuoi
FROM TONKHO
WHERE MaVTu=@MaVTu AND NamThang=@NamThang
RETURN ISNULL(@KQ,0)
END
6. Sử dụng hàm Fn_ConNhap đã tạo để viết hàm
Fn_DS_VatTuConNhap (@SoDH) liệt kê SoDH, MaVTu, TenVTu,
SLConNhap của các vật tư chưa nhập đủ.

CREATE FUNCTION Fn_DS_VatTuConNhap (@SoDH CHAR(4))
RETURNS @DSVT TABLE
(
SoDH CHAR(4),

MaVTu CHAR(4),
TenVTu VARCHAR(100),
SLConNhap INT
)
AS
BEGIN
INSERT INTO @DSVT
SELECT SoDH, a.MaVTu, TenVTu,
dbo.Fn_ConNhap(SoDH,a.MaVTu)
FROM CTDONDH a INNER JOIN VATTU b ON
a.MaVTu=b.MaVTu
WHERE SoDH=@SoDH
DELETE @DSVT WHERE SLConNhap < = 0
RETURN
END
7. Fn_CongThang(@NamThang, @n) trả về chuỗi năm tháng mới có
cộng đi n tháng (n là một số nguyên). Chú ý: @NamThang là chuỗi
có dạng YYYYMM.
19


CREATE FUNCTION Fn_CongThang ( @NamThang CHAR(6), @n INT)
RETURNS CHAR(6)
BEGIN
DECLARE @KQ CHAR(6), @Ngay DATETIME
SET @Ngay= RIGHT (@NamThang,2)+ '/' +'1'+ '/'+
LEFT(@NamThang,4)
SET @Ngay = DATEADD(mm,@n,@Ngay)
SET @KQ = CONVERT(CHAR(6),@Ngay,112)
RETURN ISNULL(@KQ,0)

END
8.

Sử dụng hàm Fn_TonCuoi và Fn_CongThang đã tạo để viết hàm
Fn_DS_TonKho_Lech_1Thang (@NamThang) liệt kê các thông tin
trong bảng tồn kho của các vật tư mà thông tin tồn đầu kỳ của năm
tháng truyền vào không bằng thông tin tồn cuối kỳ của năm tháng
trước.

CREATE FUNCTION Fn_DS_TonKho_Lech_1Thang (@NamThang
CHAR(6))
RETURNS @DSTKLech1Thang TABLE
(
MaVTu CHAR(4),
SLDau INT,
SLCuoi INT
)
BEGIN
DECLARE @NamThang_Truoc CHAR(6)
SET @NamThang_Truoc = dbo.Fn_CongThang(@NamThang,-1)
INSERT INTO @DSTKLech1Thang
SELECT MaVTu, SLDau,
dbo.Fn_TonCuoi(@NamThang_Truoc,MaVTu)
FROM TONKHO
WHERE NamThang=@NamThang
DELETE @DSTKLech1Thang WHERE SLDau=SLCuoi
20


RETURN

END
9. Hàm trả về một bảng gồm các thông tin: SoPN, NgayNhap, Tổng
tiền nhâp ( với tham số truyền vào là SoPN)

CREATE FUNCTION Fn_DSPNHAP (@SoPN CHAR(4)) RETURNS
TABLE
AS
RETURN( SELECT a.SoPN, NgayNhap, SUM(SLNhap*DGNhap)AS
TongTienNhap
FROM PNHAP a INNER JOIN CTPNHAP b
ON a.SoPN=b.SoPN WHERE a.SoPN=@SoPN GROUP BY a.SoPN,
NgayNhap)
GO
10.
Viết hàm trả về một bảng gồm các thông tin: SoPX, NgayXuat,
TongTienXuat ( với tham số truyền vào là SoPX)

CREATE FUNCTION Fn_DSPXUAT (@SoPX CHAR(4)) RETURNS
TABLE
AS
RETURN( SELECT a.SoPX, NgayXuat, SUM(SLXuat*DGXuat)AS
TongTienXuat FROM PXUAT a INNER JOIN CTPXUAT b ON
a.SoPX=b.SoPX WHERE a.SoPX=@SoPX GROUP BY a.SoPX, NgayXuat)
GO

21


VII. Tạo các Trigger sau:
1. Xây dựng Trigger khi thêm mới dữ liệu vào bảng PNHAP với tên

tg_PNHAP_Them. Trong đó cần kiểm tra các ràng buộc dữ liệu
phải hợp lệ.
- Số đặt hàng phải có trong bảng DONDH.
- Ngày nhập hàng phải sau ngày đặt hàng.

CREATE TRIGGER tg_PNHAP_Them ON PNHAP
FOR INSERT
AS
DECLARE @SoDH CHAR(4), @NgayNhap DATETIME
SELECT @SoDH=SoDH, @NgayNhap=NgayNhap FROM
INSERTED
IF NOT EXISTS (SELECT * FROM DONDH WHERE
SoDH=@SoDH)
BEGIN
RAISERROR ('Số đơn hàng này chưa có trong bảng DONDH nên
không thêm được',16,1)
ROLLBACK TRAN
RETURN
END
DECLARE @NgayDH DATETIME
SELECT @NgayDH=NgayDH FROM DONDH WHERE
SoDH=@SoDH
IF @NgayNhap < @NgayDH
BEGIN
RAISERROR ('Ngày nhập hàng phải sau ngày đặt hàng',16,1)
ROLLBACK TRAN
RETURN
END
GO
22



2. Xây dựng trigger khi thêm mới dữ liệu vào bảng CTPNHAP với tên
tg_CTPNHAP_Them . Trong đó cần kiểm tra các ràng buộc dữ liệu
phải hợp lệ:
- Số lượng nhập hàng <= (Số lượng đặt – Tổng số lượng đã nhập vào
trước đó)
CREATE TRIGGER tg_CTPNHAP_Them ON CTPNHAP
FOR INSERT
AS
DECLARE @SoDH CHAR(4), @MaVTu CHAR(4),@SLDat INT,
@SoPN CHAR(4), @SLNhap INT, @TongNhap INT
SELECT @SoDH=PNHAP.SoDH,
@SoPN=INSERTED.SoPN,@MaVTu=INSERTED.MaVTu,@SLNhap=SLN
hap FROM INSERTED INNER JOIN PNHAP ON
INSERTED.SoPN=PNHAP.SoPN
SELECT @TongNhap=SUM(SLNhap) FROM CTPNHAP INNER
JOIN PNHAP ON CTPNHAP.SoPN=PNHAP.SoPN WHERE
PNHAP.SoDH=@SoDH AND CTPNHAP.MaVTu=@MaVTu AND @SoPN
NOT IN (SELECT CTPNHAP.SoPN FROM CTPNHAP INNER JOIN
INSERTED ON CTPNHAP.SoPN<>INSERTED.SoPN)
SELECT @SLDat=SLDat FROM CTDONDH WHERE
SoDH=@SoDH AND MaVTu=@MaVTu
IF @SLNhap>@SLDat-@TongNhap
BEGIN
RAISERROR ('Bạn đã nhập quá nhiều hàng',16,1)
ROLLBACK TRAN
RETURN
END
GO

3. Xây dựng Trigger khi xóa dữ liệu trong bảng PXUAT với tên
tg_PXUAT_Xóa .Trong đó cần thực hiện các hành động:
- Thực hiện tự động xóa các dòng dữ liệu liên quan bên bảng
CTPXUAT
CREATE TRIGGER tg_PXUAT_Xoa ON PXUAT
23


FOR DELETE
AS
DECLARE @SoPX CHAR(4), @NgayXuat DATETIME, @TenKH
VARCHAR(100)
SELECT @SoPX=SoPX, @NgayXuat=NgayXuat, @TenKH=TenKH
FROM DELETED
DELETE CTPXUAT WHERE CTPXUAT.SoPX=@SoPX
GO

4. Xây dựng trigger khi xóa dữ liệu trong bảng PNHAP với tên
tg_PNHAP_Xoa.Trong đó cần thực hiện hành động:
-Thực hiện tự động xóa các dòng dữ liệu liên quan bảng
CTPNHAP
CREATER TRIGGER tg_PNHAP_Xoa ON PNHAP
FOR DELETER
AS
Delete from CTPXUAT Where SOPX in (Select SOPX from deleted)
5.Xây dựng trigger khi sửa dữ liệu trong bảng PNHAP với tên
tg_PNHAP_Sua. Trong đo cần kiểm tra các ràng buộc dữ liệu hợp lệ.
- Không cho phép sửa đổi giá trị của cá cột:số nhập hàng, số đặt hàng.
-Kiểm tra giá trị mới của cột ngày nhập hàng phải sau ngày đặt hàng.
CREATER TRIGGER tg_PNHAP_Sua ON PNHAP

FOR UPDATE
AS
If(UPDATE(sopn) or UPDATE(sohd))
Begin
Print ‘Không được thay đổi dữ liệu’
ROLLBACK TRANSACTION
End
DECLARE @ngaydat datetime, @ngaynhap datetime,@sodh char(4)
Select @ngaynhap=convert(char(10),ngaynhap,103),@sohd=sohd from
inserted
24


Select @ngaydat=convert(char(10),ngaydh,103) from dondh WHERE
sohd=@sohd
IF (@ngaynhap>@ngaydat)
Begin
Print ‘Dữ liệu không hợp lệ’
ROLLBACK TRANSACTION
End
6.Xây dụng trigger khi sửa dữ liệu trong bảng PXUAT với tên
tg_PXUAT_Sua. Trong đó cần kiểm tra các ràng buộc dữ liệu hợp lệ
-Không cho phép sửa đổi giá trị cột phiếu xuất
-Kiểm tra giá trị mới ngày xuất phải cùng năm tháng với giá rị cũ của
ngày xuất. Nếu khác nhau thì thông báo lỗi không cho sửa
Creater trigger tg_PXUAT_Sua ON PXUAT FOR UPDATE
AS
IF(update(sopx))
Begin
Print ‘ Không được thay đổi sopx’

Rollback transaction
End
Declare @ngaycu datetime,@ngaynmoi datetime, @sopx char(4)
Select @sopx=sopx,@ngaycu=ringt(convert(char(10),ngayxuat,103),7)
from deleted
Select @ngaymoi=right(convert(char(10),ngayxuat,103),7)from inserted
If@ngaycu!=@ngaymoi)
Begin
Print’Ngày xuất phải cùng năm tháng với ngày xuất cũ’
Rollback transaction
End

25


×