Professional Documents
Culture Documents
Quản Lý Tour Du Lịch Nha Trang
Quản Lý Tour Du Lịch Nha Trang
1
Chương I: XÂY DỰNG CƠ SỞ DỮ LIỆU
USE QLT_NHATRANG;
2
-- Tạo bảng khách hàng --
);
);
3
ID_DAILY INT NOT NULL,
);
);
);
4
-- Tạo bảng khách sạn --
);
);
5
NGAY_KT DATETIME NOT NULL DEFAULT GETDATE (),
);
-- Tạo bảng vé --
CREATE TABLE VE
);
6
-- Tạo bảng đặt vé --
);
);
7
-- Tạo bảng tour điểm tham quan--
);
TOUR (ID_TOUR)
);
INSERT INTO
KHACHHANG(ID_KH,TENKH,EMAILKH,SDTKH,DIACHIKH,CCCDKH)
VALUES
8
('201',N'Nguyễn Văn An','annguyen315@gmail.com','0925634576',N'Hà
Nội','175864'),
VALUES
('102',N'Vietravel','Nha Trang','0965287459'),
9
-- Thêm dữ liệu cho bảng hướng dẫn viên--
VALUES
VALUES
('301','Ôtô','4'),
('302','Ôtô 7','7'),
10
('303','Xe 16 ','16'),
('304','Xe 30','30'),
('305','Xe Khách','45'),
('306','Xe máy','2');
VALUES
('601','301'),
('608','301'),
('604','303'),
('602','304'),
('604','305'),
('609','301'),
('607','302'),
('607','306'),
('603','304'),
('610','301');
VALUES
('403','Alana Beach Hotel',N'7 Trần Quang Khải, Lộc Thọ, Nha Trang'),
11
-- Thêm dữ liệu cho bảng vé --
VALUES
('001',N'Vé thườnng','602','102'),
('002',N'Vé VIP','604','105'),
('006',N'Vé thường','601','104'),
('007',N'Vé VIP','603','103'),
VALUES
('001','201'),
('006','206'),
('007','207'),
('009','203'),
('008','205'),
('002','209'),
('004','203');
12
-- Thêm dữ liệu cho bảng đăng ký --
VALUES
('DK01','201','602','4'),
('DK02','203','603','16'),
('DK03','209','601','45'),
('DK04','203','609','1'),
('DK05','207','610','30'),
('DK06','206','607','10'),
('DK07','201','605','5');
VALUES
VALUES
13
('603',N'Đi để trở về','2023-03-08 07:30:00','2023-03-10 10:00:00','500000','506','703'),
VALUES
('602','701'),
('608','703'),
('603','707'),
('610','704'),
('602','702'),
('610','708'),
('603','706');
VALUES
('601','402'),
('602','401'),
14
('603','403'),
('604','404'),
('605','405'),
('606','401'),
('607','402'),
('608','405'),
('609','404'),
('610','401');
--2. Truy vấn danh sách tour cùng thông tin hướng dẫn viên và địa điểm tham quan
SELECT T.TENTOUR, HDV.TENHDV, DTQ.TENDIADANH
FROM TOUR T
JOIN HDV ON T.ID_HDV = HDV.ID_HDV
JOIN DTQ ON T.ID_DTQ = DTQ.ID_DTQ;
--3. Truy vấn danh sách tour cùng thông tin hướng dẫn viên và địa điểm tham quan
SELECT T.TENTOUR, PT.TENPT
FROM TOUR_PHUONGTIEN TP
JOIN TOUR T ON TP.ID_TOUR = T.ID_TOUR
JOIN PHUONGTIEN PT ON TP.ID_PHUONGTIEN = PT.ID_PHUONGTIEN
WHERE PT.TENPT = N'Ôtô';
--2. Truy vấn tổng số khách hàng đăng ký tham gia mỗi tour
SELECT T.TENTOUR, COUNT(DK.ID_KH) AS SoLuongKhachHang
15
FROM DANGKY DK
JOIN TOUR T ON DK.ID_TOUR = T.ID_TOUR
GROUP BY T.TENTOUR;
--3. Truy vấn tổng số khách sạn được sử dụng trong các tour và số lượng tour tương
ứng
SELECT KS.TENKS, COUNT(TK.ID_TOUR) AS SoLuongTour
FROM TOUR_KHACHSAN TK
JOIN KHACHSAN KS ON TK.ID_KHACHSAN = KS.ID_KHACHSAN
GROUP BY KS.TENKS;
--6. Truy vấn tổng số khách hàng và số lượng vé họ đã đặt, nhóm theo đại lý
SELECT DL.TENDL, COUNT(DISTINCT DV.ID_KH) AS SoLuongKhachHang,
COUNT(DV.ID_VE) AS SoLuongVe
FROM DATVE DV
JOIN VE V ON DV.ID_VE = V.ID_VE
JOIN DAILY DL ON V.ID_DAILY = DL.ID_DAILY
GROUP BY DL.TENDL;
16
--3. Hướng dẫn viên hướng dẫn hơn 1 tour
SELECT ID_HDV, COUNT(*) AS ToursGuided
FROM TOUR
GROUP BY ID_HDV
HAVING COUNT(*) > 1;
--4. Các tour có tổng giá trị vé bán được trên 1 triệu
SELECT ID_TOUR, SUM(GIA) AS TotalRevenue
FROM TOUR
GROUP BY ID_TOUR
HAVING SUM(GIA) > 1000000;
17
FROM TOUR
WHERE ID_TOUR NOT IN (SELECT ID_TOUR FROM DANGKY);
--2. Giao của các khách hàng và đại lý có cùng số điện thoại
SELECT TENKH AS Name, SDTKH AS Phone
FROM KHACHHANG
INTERSECT
SELECT TENDL AS Name, SDT AS Phone
FROM DAILY;
--3. Khách hàng không phải là hướng dẫn viên (dựa trên tên và email)
SELECT TENKH AS Name, EMAILKH AS Email
FROM KHACHHANG
EXCEPT
SELECT TENHDV AS Name, EMAIL AS Email
FROM HDV;
18
SELECT ID_KH
FROM KHACHHANG k
WHERE NOT EXISTS (
SELECT ID_TOUR
FROM TOUR t
WHERE NOT EXISTS (
SELECT ID_VE
FROM DATVE d
WHERE d.ID_KH = k.ID_KH
AND d.ID_VE IN (SELECT ID_VE FROM VE v WHERE v.ID_TOUR =
t.ID_TOUR)
)
);
--2. Các tour có tất cả các khách hàng đã đăng ký ít nhất một vé
SELECT ID_TOUR
FROM TOUR t
WHERE NOT EXISTS (
SELECT ID_KH
FROM KHACHHANG k
WHERE NOT EXISTS (
SELECT ID_VE
FROM DATVE d
WHERE d.ID_KH = k.ID_KH
AND d.ID_VE IN (SELECT ID_VE FROM VE v WHERE v.ID_TOUR =
t.ID_TOUR)
)
);
19
--5. Cập nhật số điện thoại của hướng dẫn viên
UPDATE HDV
SET SDT = '0912345678'
WHERE ID_HDV = 503;
20
-- Thủ tục này dùng để xóa thông tin của một hướng dẫn viên.
-- Thủ tục 5: Lấy danh sách các tour và hướng dẫn viên
CREATE PROCEDURE sp_GetToursAndGuides
AS
BEGIN
SELECT T.ID_TOUR, T.TENTOUR, H.TENHDV
FROM TOUR T
INNER JOIN HDV H ON T.ID_HDV = H.ID_HDV;
END;
GO
-- Thủ tục này truy vấn danh sách các tour cùng với tên của hướng dẫn viên đi
kèm.
1.2.9.2. Hàm
-- Hàm 1: Liệt kê tên của khách hàng đã đặt vé cho các tour do một hướng dẫn 502
dẫn dắt
SELECT KHACHHANG.TENKH
FROM KHACHHANG
JOIN DANGKY ON KHACHHANG.ID_KH = DANGKY.ID_KH
JOIN TOUR ON DANGKY.ID_TOUR = TOUR.ID_TOUR
WHERE TOUR.ID_HDV = '502';
--Hàm 2: Tìm tour có số lượng điểm đến khác nhau cao nhất
SELECT TOP 1 TENTOUR, COUNT(DISTINCT ID_DTQ) AS DestinationCount
FROM TOUR
JOIN TOUR_DTQ ON TOUR.ID_TOUR = TOUR_DTQ.ID_TOUR
GROUP BY TENTOUR
ORDER BY DestinationCount DESC;
--Hàm 3: Tính tổng doanh thu từ việc bán vé của mỗi đại lý du lịch
21
SELECT DAILY.TENDL, SUM(TOUR.GIA * DANGKY.SOLUONGVE) AS
TotalRevenue
FROM DAILY
JOIN VE ON DAILY.ID_DAILY = VE.ID_DAILY
JOIN TOUR ON VE.ID_TOUR = TOUR.ID_TOUR
JOIN DANGKY ON TOUR.ID_TOUR = DANGKY.ID_TOUR AND VE.ID_TOUR
= DANGKY.ID_TOUR
GROUP BY DAILY.TENDL;
--Hàm 4: Tìm chi tiết các tour (bao gồm tên tour, ngày bắt đầu, ngày kết thúc, và tên
hướng dẫn viên) có ít nhất một phương tiện có trên 30 chỗ ngồi
SELECT TOUR.TENTOUR, TOUR.NGAY_BD, TOUR.NGAY_KT,
HDV.TENHDV
FROM TOUR
JOIN TOUR_PHUONGTIEN ON TOUR.ID_TOUR =
TOUR_PHUONGTIEN.ID_TOUR
JOIN PHUONGTIEN ON TOUR_PHUONGTIEN.ID_PHUONGTIEN =
PHUONGTIEN.ID_PHUONGTIEN
JOIN HDV ON TOUR.ID_HDV = HDV.ID_HDV
WHERE CAST(PHUONGTIEN.SOCHO AS INT) > 30;
--Hàm 5: Liệt kê tên của các khách hàng đã đặt tất cả các loại vé
SELECT KHACHHANG.TENKH
FROM KHACHHANG
WHERE NOT EXISTS (
SELECT TENVE
FROM VE
EXCEPT
SELECT VE.TENVE
FROM VE
JOIN DATVE ON VE.ID_VE = DATVE.ID_VE
WHERE DATVE.ID_KH = KHACHHANG.ID_KH
);
1.2.10. Trigger
-- Trigger 1: Kiểm tra ngày kết thúc tour phải sau ngày bắt đầu
CREATE TRIGGER trg_CheckTourDates
ON TOUR
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS(SELECT * FROM inserted WHERE NGAY_KT <= NGAY_BD)
BEGIN
RAISERROR ('Ngày kết thúc tour phải sau ngày bắt đầu.', 16, 1);
ROLLBACK TRANSACTION;
END
END;
GO
-- Trigger này đảm bảo rằng ngày kết thúc của tour không thể trước ngày bắt đầu.
22
-- Trigger 2: Cập nhật số lượng vé còn lại khi có người đăng ký tour
CREATE TRIGGER trg_UpdateRemainingTickets
ON DANGKY
AFTER INSERT
AS
BEGIN
UPDATE TOUR
SET SOLUONGVE = SOLUONGVE - (SELECT SOLUONGVE FROM inserted)
WHERE ID_TOUR = (SELECT ID_TOUR FROM inserted);
END;
GO
-- Trigger này tự động cập nhật số lượng vé còn lại của tour khi có đăng ký mới.
-- Trigger 3: Kiểm tra email khách hàng có hợp lệ khi thêm mới
CREATE TRIGGER trg_ValidateCustomerEmail
ON KHACHHANG
BEFORE INSERT
AS
BEGIN
IF EXISTS(SELECT * FROM inserted WHERE NOT EMAILKH LIKE '%@%')
BEGIN
RAISERROR ('Email không hợp lệ.', 16, 1);
ROLLBACK TRANSACTION;
END
END;
GO
-- Trigger này kiểm tra xem email của khách hàng có chứa ký tự '@' khi thêm
mới vào cơ sở dữ liệu.
23
Chương II: XÂY DỰNG GIAO DIỆN CHƯƠNG TRÌNH
Bước 2: Tại Visual Studio, mở giao diện chương trình đã được xây dựng → chọn Tool
→ Connect to Database → Microsoft SQL Server
24
Bước 3: Tại Add Connection, dán Server Name đã có được từ bước 1 → chọn tên cơ
sở dữ liệu (database name) mà người dùng muốn kết nối với giao diện chương trình
Bước 4: Chọn Advanced và sao chép phần Data Source (string str = @"Data
Source=LAPTOP-09F30CN6\SQLEXPRESS;Initial Catalog=NT;Integrated
Security=True;TrustServerCertificate=True";)
Bước 5: Thoát ra, tại phần code của giao diện chương trình, khai báo SqlConnection
từ “using System.Data.SqlClient;” theo cách của bạn, ví dụ đơn giản như sau
string str = @"Data Source=LAPTOP-09F30CN6\SQLEXPRESS;Initial
Catalog=NT;Integrated Security=True;TrustServerCertificate=True";
SqlConnection connection = new SqlConnection(connectionSTR);
Bước 6: Quay lại bước 3, bấm Test Connection để kiểm tra kết nối và OK để hoàn
thành việc kết nối dữ liệu. Tại những lần kết nối sau này chỉ cần làm từ bước 1 đến
bước 3 trong trường hợp file cơ sở dữ liệu muốn kết nối không thay đổi.
25
2.2. THIẾT KẾ GIAO DIỆN
Giao diện bao đầu khi vào quản lý cơ sở dữ liệu
26