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ư
Trang 1TÀ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)
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ư
Trang 22 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
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
Trang 3FROM 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:
Trang 4IF(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
Trang 53 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 (*)
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.
Trang 6SELECT *, 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')
Trang 7IV 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
CREATE VIEW vw_DONDH_TongSLDatNhap
GROUP BY DONDH.SoDH
GO
Trang 83 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 ()
Trang 95 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 ()
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
CREATE VIEW vw_PNHAP_TongSLNhap
AS
Trang 10SELECT 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
Trang 11V 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
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
Trang 123 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
Trang 13RETURN END
IF EXISTS ( SELECT * FROM CTPNHAP WHERE
IF EXISTS ( SELECT * FROM CTPXUAT WHERE
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.
Trang 14CREATE PROCEDURE supd_VATTU_Sua @MaVTu CHAR(4), @TenVTu VARCHAR(100)=NULL, @DVTinh VARCHAR(50)=NULL,@PhanTram REAL=NULL
DVTinh = ISNULL (@DVTinh, DVTinh), PhanTram = ISNULL (@PhanTram, PhanTram) WHERE MaVTu= @MaVTu
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
Trang 15khô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
Trang 169 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)
IF NOT EXISTS (SELECT * FROM DONDH WHERE
INSERT INTO PNHAP VALUES (@SoPN,@NgayNhap,@SoDH)
GO
Trang 17VI 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
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
Trang 183 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
Trang 196 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))
Trang 20CREATE FUNCTION Fn_CongThang ( @NamThang CHAR(6), @n INT) RETURNS CHAR(6)
BEGIN
DECLARE @KQ CHAR(6), @Ngay DATETIME
SET @Ngay= RIGHT (@NamThang,2)+ '/' +'1'+ '/'+
CREATE FUNCTION Fn_DS_TonKho_Lech_1Thang (@NamThang
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
Trang 22VII 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
END
DECLARE @NgayDH DATETIME
SELECT @NgayDH=NgayDH FROM DONDH WHERE
Trang 232 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
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
Trang 24Delete 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
Trang 25Select @ngaydat=convert(char(10),ngaydh,103) from dondh WHERE
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
Select @ngaymoi=right(convert(char(10),ngayxuat,103),7)from insertedIf@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