-
Notifications
You must be signed in to change notification settings - Fork 1
/
database.sql
1367 lines (1207 loc) · 42.5 KB
/
database.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
drop database cafeshop;
create database cafeshop;
use cafeshop;
drop table if exists nhanvien;
CREATE TABLE NHANVIEN (
MaNV INT auto_increment PRIMARY KEY,
HoVaTen VARCHAR(50) NOT NULL,
email varchar(100) NOT NULL UNIQUE,
mk varchar(100) not null,
DiaChi VARCHAR(50),
NgaySinh DATE,
SDT VARCHAR(10),
MaGiamSat INT,
Luong INT,
statusNV INT default 1,
CONSTRAINT fk_NV_GIAMSAT FOREIGN KEY (MaGiamSat)
REFERENCES NHANVIEN(MaNV) ON DELETE NO ACTION
)auto_increment 1
auto_increment 1;
drop trigger if exists check_age_and_salary ;
DELIMITER //
CREATE TRIGGER check_age_and_salary
BEFORE INSERT ON NHANVIEN
FOR EACH ROW
BEGIN
IF YEAR(NOW()) - YEAR(NEW.NgaySinh) <= 16 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Tuổi phải lớn hơn 16.';
END IF;
IF NEW.Luong < 20000 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Lương phải lớn hơn hoặc bằng 20000.';
END IF;
END//
DELIMITER ;
drop table if exists DonHang;
create table DonHang (
MaDonHang int auto_increment primary key,
SoLuongMon int default 0,
TongGiaGoc int default 0,
TongGiaSauUuDai int default 0
)auto_increment 1
auto_increment 1;
drop table if exists dondattruoc;
create table DonDatTruoc (
MaDonHang int primary key,
MaBan int,
constraint Fk_dondattruoc foreign key (MaDonHang) references DonHang(MaDonHang) on delete cascade
);
drop table if exists donhangcanhan;
create table DonHangCaNhan (
MaDonHang int not null primary key,
MaKhachHang int not null,
Sothe int,
constraint Fk_donhangcanhan foreign key (MaDonHang) references DonHang(MaDonHang) on delete cascade
);
drop table if exists hoadon;
CREATE TABLE HOADON (
MaHD INT auto_increment primary KEY,
tongGia int default 0
)auto_increment 1 auto_increment 1;
drop table if exists xuat;
CREATE TABLE XUAT
( MaNV INT NOT NULL,
MaHD INT NOT NULL,
MaDH int NOT NULL,
NgayXuat DATE ,
GioXuat TIME,
PRIMARY KEY(MaNV, MaHD, MaDH),
CONSTRAINT fk_X_NHANVIEN FOREIGN KEY (MaNV)
REFERENCES NHANVIEN(MaNV),
CONSTRAINT fk_X_HOADON FOREIGN KEY (MaHD)
REFERENCES HOADON(MaHD),
CONSTRAINT fk_X_DONHANG FOREIGN KEY (MaDH)
REFERENCES DonHang(MaDonHang)
);
-- trigger dùng để cập nhật tổng tiền trong hóa đơn
drop trigger if exists updateHoaDon;
delimiter //
create trigger updateHoaDon
before insert on xuat
for each row
begin
declare price int;
select tongGiaSauUuDai into price
from donhang
where madonhang = new.MaDH;
update hoadon
set tonggia = price
where MaHD=new.MaHD;
end //
delimiter ;
-- trigger dùng để xóa hóa đơn
drop trigger if exists setdefaultHoaDon;
delimiter //
create trigger setdefaultHoaDon
before delete on xuat
for each row
begin
update hoadon
set tonggia = 0
where MaHD=old.MaHD;
end //
delimiter ;
drop table if exists VOUCHER_TYPE;
CREATE TABLE VOUCHER_TYPE(
id INT auto_increment KEY,
discount_percent INT not null,
note VARCHAR(200) ,
max_discount INT,
number INT default '0'
) auto_increment 1
auto_increment 1;
drop table if exists VOUCHER_CARD;
CREATE TABLE VOUCHER_CARD(
id INT,
STT INT ,
current_status int default 1,
PRIMARY KEY(id,STT),
constraint Fk_voucher_card foreign key (id) references VOUCHER_TYPE(id) ON DELETE CASCADE
) ;
-- trigger cập nhật số lượng loại voucher tương ứng khi một thẻ voucher được thêm
DROP TRIGGER IF EXISTS add_voucher_num;
DELIMITER //
create trigger add_voucher_num
after insert on VOUCHER_CARD
for each row
begin
update VOUCHER_TYPE
SET number=number+1
WHERE VOUCHER_TYPE.id = new.id;
end //
DELIMITER ;
-- trigger cập nhật số lượng loại voucher tương ứng khi một thẻ voucher bị xóa
DROP TRIGGER IF EXISTS delete_voucher_num;
delimiter //
create trigger delete_voucher_num
before delete on VOUCHER_CARD
for each row
begin
update VOUCHER_TYPE
SET number=number-1
where VOUCHER_TYPE.id = old.id;
end //
delimiter ;
-- bởi vì trong nghiệp vụ chỉ có thêm hoặc xóa vào bảng voucher_card. Bảng này chỉ được tạo ra để quản lí chính xác số lượng thẻ voucher cho mỗi loại voucher nên chỉ có hai thao tác chính là thêm và xóa.
-- thủ tục này kiểm tra thẻ voucher đang muốn thêm đã có sẵn và đang khả dụng trong cửa hàng hay không mà đưa ra cách xử lí hợp lí
-- input: mã voucher, số thứ tự thẻ voucher
-- kết quả: thẻ đã được thêm hoặc cập nhật trạng thái phù hợp
drop procedure if exists addVoucher_card;
delimiter //
create procedure addVoucher_card (voucher_id int , STT_voucher int)
begin
declare checkExist int ;
declare state int;
set state =2;
set checkExist =0;
drop temporary table if exists t3;
create temporary table t3 as
select *
from voucher_card
where id = voucher_id and STT = STT_voucher;
select count(*) into checkExist
from t3;
if (checkExist = 1) then
select current_status into state
from t3;
if (state =0) then SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ voucher đã được sử dụng';
else SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ voucher đang có sẵn';
end if;
else
insert into voucher_card (id,STT) values (voucher_id, STT_voucher);
end if;
end //
delimiter ;
-- thủ tục xóa voucher_card
drop procedure if exists deleteVoucher_card;
delimiter //
create procedure deleteVoucher_card (voucher_id int, STT_voucher int)
begin
declare state int ;
select current_status into state
from voucher_card
where id = voucher_id and STT = STT_voucher;
if (state =1) then
update voucher_card
set current_status =0
where id = voucher_id and STT = STT_voucher;
update voucher_type
set number = number -1
where id = voucher_id;
elseif (state =0 ) then SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ đang không khả dụng';
else SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ không tồn tại';
end if;
end //
delimiter ;
drop table if exists voucher_effective_time;
CREATE TABLE VOUCHER_EFFECTIVE_TIME(
id INT Primary key,
start_time DATE,
end_time DATE,
constraint Fk_effective_time foreign key (id) references VOUCHER_TYPE(id) ON DELETE CASCADE
);
drop table if exists payment_apply;
CREATE TABLE PAYMENT_APPLY(
order_id INT unique not null,
STT_voucher INT,
id_voucher INT,
PRIMARY KEY(STT_voucher,id_voucher),
constraint Fk_payment_apply1 foreign key (id_voucher,STT_voucher) references VOUCHER_CARD(id,STT) ON DELETE CASCADE,
constraint Fk_payment_apply2 foreign key (order_id) references DonHang(MaDonHang) ON DELETE CASCADE
);
drop table if exists customers;
CREATE TABLE customers (
ID INT auto_increment PRIMARY KEY,
name VARCHAR(100) NOT NULL,
address VARCHAR(300) NOT NULL,
CONSTRAINT uniqueCustomer UNIQUE(name, address)
)auto_increment=1
auto_increment=1;
drop table if exists customerPN;
CREATE TABLE customerPN (
id INT NOT NULL auto_increment PRIMARY KEY,
customerID INT NOT NULL,
phoneNumber VARCHAR(50) NOT NULL,
FOREIGN KEY (customerID) REFERENCES customers(ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT phoneLength CHECK (length(phoneNumber) >= 10 AND length(phoneNumber) <= 11)
) auto_increment 1
auto_increment 1;
drop table if exists bookingTables;
CREATE TABLE bookingTables (
ID INT auto_increment PRIMARY KEY,
image varchar(255),
seats INT NOT NULL,
current_status INT NOT NULL DEFAULT 1 ,
CONSTRAINT enum_current_status CHECK(current_status in ('0','1'))
)auto_increment 1
auto_increment 1;
drop table if exists bookingInfo;
CREATE TABLE bookingInfo (
ID INT auto_increment PRIMARY KEY,
fk_tableID INT DEFAULT 0,
fk_customerID INT DEFAULT 0,
orderDate DATE NOT NULL,
orderTime time not null,
startDate date not null,
startTime TIME NOT NULL,
endTime TIME NOT NULL,
CONSTRAINT startTime_endTime CHECK (startTime < endTime),
constraint Fk_booking1 FOREIGN KEY (fk_tableID) REFERENCES bookingTables(ID) ON DELETE SET null ON UPDATE CASCADE,
constraint Fk_booking2 FOREIGN KEY (fk_customerID) REFERENCES customers(ID) ON DELETE SET null ON UPDATE CASCADE
);
drop table if exists LoaiMon;
CREATE TABLE LoaiMon (
Maloaimon int auto_increment not null,
Mota varchar(255),
image varchar(255),
Ten varchar(50) not null,
Giobatdau Time,
Gioketthuc Time,
Loaimon varchar(255) not null DEFAULT 'Do uong',
CONSTRAINT enum_Loai_mon CHECK(Loaimon in ('Do an', 'Do uong')),
PRIMARY KEY (Maloaimon)
) auto_increment 1
auto_increment 1;
drop table if exists mon;
CREATE TABLE Mon (
Maloaimon int not null,
Kichco varchar(255) not null DEFAULT 'M',
Dongia int not null,
current_status int default 1 ,
CONSTRAINT enum_Kich_co1 CHECK(Kichco in ('M','L','XL')),
CONSTRAINT fk_Ma_loai_mon FOREIGN KEY (Maloaimon)
REFERENCES loaimon(Maloaimon) ON DELETE CASCADE,
PRIMARY KEY (Maloaimon, Kichco)
);
-- thủ tục giúp xóa món trong cửa hàng bằng cách cho current_status = 0
delimiter //
create procedure xoamon (dish_id int, size char(1))
begin
update mon
set current_status = 0
where maloaimon=dish_id and kichco = size;
end //
delimiter ;
-- thủ tục thêm hoặc cập nhật món mới vào của hàng
-- input: mã món, kích cỡ, giá
-- kết quả: nếu món đã tồn tại thì cập nhật lại đơn giá, ngược lại thì insert món vào bảng mon
drop procedure if exists themmon;
delimiter //
create procedure themmon (dish_id int, size char(2), price int)
begin
if exists (select maloaimon, Kichco from mon where maloaimon = dish_id and Kichco = size) THEN
update mon set current_status = 1, dongia = price where maloaimon = dish_id and Kichco = size;
else INSERT INTO mon (maloaimon, kichco, dongia)
VALUES (dish_id, size, price);
end if;
end //
delimiter ;
CREATE TABLE thuocvemon (
Mamon int not null,
Madonhang int not null,
Kichco char(1) not null DEFAULT 'M',
Giatheongay int not null,
Soluong int not null,
CONSTRAINT enum_Kich_co2 CHECK(Kichco in ('M','L','XL')),
CONSTRAINT fk_Ma_don_hang FOREIGN KEY (Madonhang) REFERENCEs donhang(madonhang) ON DELETE CASCADE,
CONSTRAINT fk_thuocvemon FOREIGN KEY (Mamon, Kichco)
REFERENCES mon(Maloaimon, Kichco) ON DELETE CASCADE,
PRIMARY KEY (Mamon, Madonhang, Kichco)
);
-- tạo thủ tục in ra thông tin đơn hàng cá nhân, thông qua ma đơn hàng
drop procedure if exists showOrderInfo;
delimiter //
create procedure showOrderInfo( order_id int)
begin
select Mamon, Ten as TenMon,Kichco,Soluong,giatheongay,(Soluong*giatheongay) as tong_gia
from thuocvemon, loaimon
where Madonhang=order_id and mamon=Maloaimon;
end //
delimiter ;
-- tạo trigger cập nhật tổng giá gốc và tổng số lượng trong đơn hàng khi thêm hàng vào thuocvemon
drop trigger if exists afterIncreaseThuocvemon
delimiter //
create trigger afterIncreaseThuocvemon
after insert on thuocvemon
for each row
begin
declare voucher_id2 int;
select id_voucher into voucher_id2
from payment_apply
where order_id = new.madonhang;
if ( voucher_id2 is not null) then call tinhTongGiaUuDai (voucher_id2, new.madonhang);
end if;
call TongGiaVaTongMon(new.madonhang);
end//
delimiter ;
-- tạo trigger cập nhật tổng giá gốc và tổng số lượng trong đơn hàng khi xóa hàng từ thuocvemon
drop trigger if exists afterDeleteThuocvemon;
delimiter //
create trigger afterDeleteThuocvemon
after delete on thuocvemon
for each row
begin
declare voucher_id int;
select id_voucher into voucher_id
from payment_apply
where order_id = old.madonhang;
if ( voucher_id is not null) then call tinhTongGiaUuDai (voucher_id, old.madonhang);
end if;
call TongGiaVaTongMon (old.madonhang);
end//
delimiter ;
-- tạo trigger cập nhật tổng giá gốc và tổng số lượng và tổng trong đơn hàng khi sửa hàng trong thuocvemon
drop trigger if exists afterUpdateThuocvemon;
delimiter //
create trigger afterUpdateThuocvemon
after update on thuocvemon
for each row
begin
declare voucher_id1 int;
declare voucher_id2 int;
select id_voucher into voucher_id1
from payment_apply
where order_id = old.madonhang;
if ( voucher_id1 is not null) then call tinhTongGiaUuDai (voucher_id1, old.madonhang);
end if;
select id_voucher into voucher_id2
from payment_apply
where order_id = new.madonhang;
if ( voucher_id2 is not null) then call tinhTongGiaUuDai (voucher_id2, new.madonhang);
end if;
call TongGiaVaTongMon (old.madonhang);
call TongGiaVaTongMon (new.madonhang);
end//
delimiter ;
-- thủ tục cập nhật thuộc tính tổng giá gốc, số lượng món
drop procedure if exists TongGiaVaTongMon;
delimiter //
create procedure TongGiaVaTongMon(orderId int )
begin
DECLARE totalCount INT DEFAULT 0;
DECLARE totalPrice INT DEFAULT 0;
select sum(soluong) into totalCount
from thuocvemon
where madonhang=orderId
group by madonhang;
select sum(soluong*giatheongay) into totalPrice
from thuocvemon
where madonhang=orderId
group by madonhang;
update donhang
set soluongmon = totalCount, tonggiagoc = totalPrice
where madonhang = orderId;
end //
delimiter ;
-- produre hiển thì danh sách các loại món chưa có món (chưa có món hoặc chỉ có các món có current_status = 0)
delimiter //
create procedure showLoaiMonRong()
begin
drop temporary table if exists t4;
create temporary table t4 as
select *
from loaimon
where (select count(*) from mon where loaimon.maloaimon=mon.maloaimon) > (select count(*) from mon where loaimon.maloaimon=mon.maloaimon and mon.current_status = 0);
select *
from loaimon
where loaimon.maloaimon not in (select t4.maloaimon from t4);
end //
delimiter ;
CREATE TABLE dieukienapdung (
Maloaimon int not null,
Mavoucher int not null,
Kichco char(1) not null DEFAULT 'M',
minNum int not null,
CONSTRAINT enum_Kich_co3 CHECK(Kichco in ('M','L','XL')),
CONSTRAINT fk_dkapdung FOREIGN KEY (Maloaimon, Kichco)
REFERENCES mon(Maloaimon, Kichco) ON DELETE CASCADE,
CONSTRAINT fk_Voucher FOREIGN KEY (Mavoucher)
REFERENCES VOUCHER_TYPE(id),
PRIMARY KEY (Maloaimon, Mavoucher, Kichco)
);
-- trigger kích hoạt sau khi thêm hàng vào payment apply
-- kết quả: thuộc tính tổng giá sau ưu đãi đã được cập nhật
drop trigger if exists afterInsertPaymentApply;
delimiter //
create trigger afterInsertPaymentApply
after insert on payment_apply
for each row
begin
call tinhTongGiaUuDai (new.id_voucher, new.order_id);
end //
delimiter ;
-- trigger kích hoat sau khi thay đổi hàng trong payment apply
-- kết quả: thuộc tính tổng giá sau ưu đãi đã được cập nhật
drop trigger if exists afterUdatePaymentApply;
delimiter //
create trigger afterUdatePaymentApply
after update on payment_apply
for each row
begin
call tinhTongGiaUuDai (null, old.order_id);
call tinhTongGiaUuDai (new.id_voucher, new.order_id);
end //
delimiter ;
-- trigger kích hoạt sau khi xóa hàng trong payment apply (một đơn hàng không còn được áp dụng voucher nữa)
-- kết quả: thuộc tính tổng giá sau ưu đãi đã được cập nhật
drop trigger if exists afterDeletePaymentApply;
delimiter //
create trigger afterDeletePaymentApply
after delete on payment_apply
for each row
begin
update donhang
set tongGiaSauUuDai = tongGiaGoc
where MaDonHang = old.order_id;
end //
delimiter ;
-- thủ tục update thuộc tính tổng giá sau ưu đãi của đơn hàng sau khi áp dụng voucher
-- input: mã voucher, mã đơn hàng
-- output: thuộc tính tổng giá sau ưu đãi đã được cập nhật
drop procedure if exists tinhTongGiaUuDai;
delimiter //
create procedure tinhTongGiaUuDai (voucher_id int , order_id int)
begin
declare applyCondition int ;
declare priceWithVoucher int;
declare discount_total_percent int default 0;
declare discount_max int default 0;
select tonggiagoc into priceWithVoucher
from donhang
where donhang.Madonhang=order_id;
drop temporary table if exists t1;
create temporary table t1 as
select *
from dieukienapdung,voucher_effective_time
where mavoucher=voucher_id and current_date()>= start_time and current_date()<= end_time;
drop temporary table if exists t2;
create temporary table t2 as
select *
from thuocvemon
where madonhang=order_id;
drop temporary table if exists t3;
create temporary table t3 as
SELECT t1.Maloaimon,t2.Kichco,t2.soluong,t1.minNum
FROM t1 JOIN t2 ON t1.Kichco = t2.Kichco AND t1.Maloaimon = t2.Mamon;
select count(*) into applyCondition
from t3
where soluong >= minNum;
if (applyCondition > 0) then
select discount_percent into discount_total_percent
from voucher_type
where id=voucher_id;
select voucher_type.max_discount into discount_max
from voucher_type
where id=voucher_id;
end if;
if (priceWithVoucher*discount_total_percent/100 > discount_max) then
set priceWithVoucher=priceWithVoucher-discount_max;
else
set priceWithVoucher=priceWithVoucher-priceWithVoucher*discount_total_percent/100;
end if;
update donhang
set tonggiasauUuDai = priceWithVoucher
where madonhang=order_id;
end //
delimiter ;
-- Bổ sung BTL2
-- Thủ tục thêm nhân viên
DELIMITER //
CREATE PROCEDURE ThemNhanVien(
IN HoVaTenParam VARCHAR(50),
IN EmailParam VARCHAR(100),
IN MatKhauParam VARCHAR(100),
IN DiaChiParam VARCHAR(50),
IN NgaySinhParam DATE,
IN SDTParam VARCHAR(10),
IN MaGiamSatParam INT,
IN LuongParam INT
)
BEGIN
DECLARE age INT;
SET age = YEAR(NOW()) - YEAR(NgaySinhParam);
IF age <= 16 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Tuổi phải lớn hơn 16.';
END IF;
IF LuongParam < 20000 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Lương phải lớn hơn hoặc bằng 20000.';
END IF;
INSERT INTO NHANVIEN
SET HoVaTen = HoVaTenParam,
email = EmailParam,
mk = MatKhauParam,
DiaChi = DiaChiParam,
NgaySinh = NgaySinhParam,
SDT = SDTParam,
MaGiamSat = MaGiamSatParam,
Luong = LuongParam;
END //
DELIMITER ;
-- thủ tục xóa nhân viên
DELIMITER //
CREATE PROCEDURE XoaNhanVien(
IN MaNVParam INT
)
BEGIN
UPDATE NHANVIEN SET statusNV = 0 WHERE MaNV = MaNVParam;
END //
DELIMITER ;
-- thủ tục giúp admin sửa lương và mã giám sát của nhân viên
DELIMITER //
CREATE PROCEDURE SuaLuongVaMaGiamSatNhanVien(
IN MaNVParam INT,
IN LuongMoi INT,
IN MaGiamSatMoi INT
)
BEGIN
IF MaGiamSatMoi = MaNVParam THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Mã giám sát mới không được trùng với mã nhân viên.';
END IF;
IF LuongMoi < 20000 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Lương phải lớn hơn hoặc bằng 20000.';
END IF;
IF MaGiamSatMoi IS NOT NULL AND NOT EXISTS (SELECT 1 FROM NHANVIEN WHERE MaNV = MaGiamSatMoi AND statusNV = 1) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Mã giám sát không tồn tại hoặc đã nghỉ việc.';
END IF;
IF (SELECT statusNV FROM NHANVIEN WHERE MaNV = MaNVParam) = 1 THEN
UPDATE NHANVIEN
SET Luong = LuongMoi,
MaGiamSat = MaGiamSatMoi
WHERE MaNV = MaNVParam;
ELSE
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Nhân viên đã nghỉ việc.';
END IF;
END //
DELIMITER ;
DELIMITER //
-- thủ tục giúp nhân viên tự sửa thông tin cá nhân của bản thân (ngoại trừ lương và mã giám sát)
DELIMITER //
CREATE PROCEDURE SuaThongTinNhanVien(
IN MaNVParam INT,
IN HoVaTenParam VARCHAR(50),
IN EmailParam VARCHAR(100),
IN MatKhauParam VARCHAR(100),
IN DiaChiParam VARCHAR(50),
IN NgaySinhParam DATE,
IN SDTParam VARCHAR(10)
)
BEGIN
DECLARE age INT;
SET age = YEAR(NOW()) - YEAR(NgaySinhParam);
IF age <= 16 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Tuổi phải lớn hơn 16.';
END IF;
IF (SELECT statusNV FROM NHANVIEN WHERE MaNV = MaNVParam) = 1 THEN
UPDATE NHANVIEN
SET HoVaTen = HoVaTenParam,
email = EmailParam,
mk = MatKhauParam,
DiaChi = DiaChiParam,
NgaySinh = NgaySinhParam,
SDT = SDTParam
WHERE MaNV = MaNVParam;
ELSE
SELECT 'Nhân viên đã nghỉ việc';
END IF;
END //
DELIMITER ;
-- thủ tục in ra thông tin của nhân viên và số hóa đơn mà nhân viên đó đã xuất với điều kiện nhân viên đó phải có số tiền lương không vượt quá số tiền đã nhập
-- input: Lương tối đa
-- output: Bảng gồm mã nhân viên, họ và tên, Lương, Số lượng hóa đơn
DELIMITER //
CREATE PROCEDURE InThongTinNhanVienVaHoaDon(
IN LuongToiDa INT
)
BEGIN
SELECT
NV.MaNV as id,
NV.HoVaTen as HoVaTen,
NV.Luong as Luong,
COUNT(X.MaDH) AS SoLuongHoaDon
FROM
NHANVIEN NV
LEFT JOIN
XUAT X ON NV.MaNV = X.MaNV
WHERE
NV.Luong <= LuongToiDa AND NV.statusNV = 1
GROUP BY
NV.MaNV
ORDER BY
NV.MaNV;
END //
DELIMITER ;
-- Hàm trả về tổng doanh thu của một bàn trong một khoảng thời gian
-- input: mã bàn, ngày bắt đầu, giờ bắt đầu, ngày kết thúc, giờ kết thúc
-- output: tổng tiền thu được trong khoảng thời gian đã nhập
DELIMITER //
CREATE FUNCTION TongTienTheoBan(
MaBanParam INT,
NgayBatDauParam DATE,
GioBatDauParam TIME,
NgayKetThucParam DATE,
GioKetThucParam TIME
)
RETURNS INT
READS SQL DATA
BEGIN
DECLARE TongTien INT;
CREATE TEMPORARY TABLE TempTable
AS
SELECT
COALESCE(DH.TongGiaSauUuDai, 0) AS TongGiaSauUuDai
FROM
bookingTables BT
JOIN
DonDatTruoc DDT ON BT.ID = DDT.MaBan
JOIN
bookingInfo BI ON BT.ID = BI.fk_tableID
JOIN
DonHang DH ON DDT.MaDonHang = DH.MaDonHang
WHERE
BT.ID = MaBanParam
AND (BI.startDate > NgayBatDauParam
OR (BI.startDate = NgayBatDauParam
AND BI.startTime >= GioBatDauParam))
AND (BI.startDate < NgayKetThucParam
OR (BI.startDate = NgayKetThucParam
AND BI.endTime <= GioKetThucParam));
SELECT SUM(TongGiaSauUuDai) INTO TongTien FROM TempTable;
DROP TEMPORARY TABLE IF EXISTS TempTable;
RETURN COALESCE(TongTien, 0);
END //
DELIMITER ;
-- Hàm này tính toán tổng số doanh thu của một người khách đã đóng góp cho của hàng và trả về chuỗi thông báo quy định sẵn cho mỗi mức độ đóng góp tương ứng của khách
-- Input: mã khách hàng
-- Output: chuỗi kí tự thể hiện mức độ đóng góp của khách
DELIMITER //
CREATE FUNCTION MucDoDongGopCustomer(
MaKhachHangParam INT
)
RETURNS VARCHAR(50)
READS SQL DATA
BEGIN
DECLARE TongTien INT;
SELECT
SUM(DH.TongGiaSauUuDai) INTO TongTien
FROM
DonHang DH
JOIN
DonHangCaNhan DHCN ON DH.MaDonHang = DHCN.MaDonHang
WHERE
DHCN.MaKhachHang = MaKhachHangParam;
IF TongTien >= 3000000 THEN
RETURN 'VIP_Customer';
ELSEIF TongTien >= 500000 THEN
RETURN 'normal_customer';
ELSE
RETURN 'new_customer';
END IF;
END //
DELIMITER ;
-- thủ tục tìm kiếm nhân viên theo tên
DELIMITER //
CREATE PROCEDURE TimKiemNhanVien(
IN TuKhoa VARCHAR(50)
)
BEGIN
SELECT *
FROM NHANVIEN
WHERE HoVaTen LIKE CONCAT('%', TuKhoa, '%');
END //
DELIMITER ;
-- thủ tục sắp xếp nhân viên theo thứ tự alphabet của tên
DELIMITER //
CREATE PROCEDURE SapXepNhanVienTheoTen()
BEGIN
SELECT
*
FROM
NHANVIEN
WHERE
statusNV = 1
ORDER BY
SUBSTRING_INDEX(HoVaTen, ' ', -1) COLLATE utf8mb4_unicode_ci;
END //
delimiter ;
-- thêm các khóa ngoại còn thiếu
alter table dondattruoc add constraint Fk_dondattruoc1 foreign key (maban) references bookingTables(ID) on delete set null;
alter table DonHangCaNhan add constraint Fk_donhangcanhan1 foreign key (MaKhachHang) references customers(ID) on delete cascade;
-- hàm giúp tạo đơn hàng cá nhân khi có khách vào, đồng thời validate thẻ voucher mà khách sử dụng (nếu có)
-- input: tên khách hàng, địa chỉ, số thẻ (của đơn hàng cá nhân), mã voucher , STT tương ứng của voucher
-- output: mã đơn hàng mới vừa được tạo ra cho khách
delimiter //
create function insertAndGetID (
tenKH varchar(100),
diachi varchar(200),
sothe int,
id_voucher int ,
STT_voucher int
)
returns int
reads sql data
begin
declare khachID int;
declare donhangID int;
declare existsCustomer int;
declare check_voucher int;
declare state int;
declare start_date date;
declare end_date date;
-- kiểm tra khách hàng này đã từng mua ở cửa hàng chưa
drop temporary table if exists s1;
create temporary table s1 as
select * from customers
where name = tenKH and address = diachi;
select count(*) into existsCustomer
from s1;
-- lấy ID của khách vừa đặt hàng
if ( existsCustomer=0) then
insert into customers (name,address) values (tenKH,diachi);
select max(ID) into khachID
from customers;
else
select ID into khachID
from s1;
end if;
-- tạo đơn hàng mới và lấy mã đơn hàng
insert into donhang() values ();
select max(MaDonHang) into donhangID
from donhang;
-- tạo đơn hàng cá nhân từ ID khách, số thẻ, ID đơn hàng
insert into donhangcanhan values (donhangID,khachID,sothe);
-- kiểm tra có áp dụng được voucher hay không
if (id_voucher is not null and STT_voucher is not null) then
select count(*) into check_voucher
from voucher_card
where voucher_card.id=id_voucher and STT_voucher=voucher_card.STT;
-- validate voucher có tồn tại trong hệ thống hay không
if (check_voucher=1) then
-- lấy tình trạng hiện tại của thẻ voucher
select current_status into state
from voucher_card
where voucher_card.id=id_voucher and STT_voucher=voucher_card.STT;
-- lấy thời gian bắt đầu sử dụng của thẻ voucher
select start_time into start_date
from voucher_effective_time
where id = id_voucher ;
-- lấy thời gian kết thúc sử dụng của thẻ voucher
select end_time into end_date
from voucher_effective_time
where id = id_voucher ;
-- validate thẻ voucher có khả năng sử dụng không
if (state = 0) then SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ voucher đã qua sử dụng';
elseif (current_date() > end_date) then SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ voucher đã hết hạn';
elseif (current_date() < start_date) then SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ voucher chưa khả dụng';
end if;
else SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = 'thẻ voucher không tồn tại';
end if;
end if;
return donhangID;
end //
delimiter ;
-- thủ tục dùng thẻ voucher để áp dụng thanh toán cho đơn hàng
delimiter //
create procedure applyVoucherForOrder ( order_id int, id_voucher int,STT_voucher int)
begin
insert into payment_apply values (order_id, STT_voucher, id_voucher);
call deleteVoucher_card(id_voucher,STT_voucher);
end //
delimiter ;
INSERT INTO NHANVIEN (hovaten,email,mk,diachi,ngaysinh,sdt,magiamsat,luong)
VALUES
( 'Nguyen Minh Diem','minhdiem@gmail.com','123456', 'Tp.A', '1990-01-19', '0909110000',null, 50000),
( 'Vo Van Kha','vankha@gmail.com','123456', 'Tp.A', '2000-01-01', '0909120000', 1, 20000),
('Nguyen Le Phuc','lephuc@gmail.com','123456','Tp.A','2000-02-01','0909130000',1,20000),
('Le Nguyen Chuong','chuongle@gmail.com','123456','Tp.A','2000-02-01','0909130000',1,20000),
('Ho Huy Hoang','huyhoang@gmail.com','123456','Tp.A','2000-02-01','0909130000',1,20000),
('Nguyen Van A', 'vana@gmail.com', 'password123', 'Hanoi', '1995-05-10', '0912345678', NULL, 45000),
('Tran Thi B', 'thib@gmail.com', 'secret456', 'Ho Chi Minh City', '1990-03-15', '0987654321', 2, 30000),
('Le Van C', 'levc@gmail.com', 'mypassword', 'Da Nang', '1988-12-20', '0901122334', 1, 40000),
('Pham Thi D', 'phamd@gmail.com', 'securepass', 'Hue', '1993-07-01', '0978123456', 3, 35000),
('Hoang Van E', 'hoange@gmail.com', 'topsecret', 'Can Tho', '1998-11-25', '0918765432', 2, 28000),
('Tran Van F', 'tranf@gmail.com', 'myp@ss', 'Hai Phong', '1992-09-03', '0965432109', 1, 38000),
('Nguyen Thi G', 'nguyeng@gmail.com', 'password123', 'Quang Ninh', '1996-02-28', '0932111222', 3, 32000),
('Le Van H', 'leh@gmail.com', 'secretp@ss', 'Vinh', '1985-06-07', '0945678901', NULL, 50000),
('Pham Van I', 'phami@gmail.com', 'myp@ssword', 'Dak Lak', '1987-04-12', '0923456789', 2, 42000),
('Ho Thi K', 'hok@gmail.com', 'mysecret', 'Nha Trang', '1991-10-15', '0909876543', 1, 37000),
('Vo Van L', 'vol@gmail.com', 'secure123', 'Buon Ma Thuot', '1997-08-20', '0956789012', 3, 31000),
('Le Van M', 'lem@gmail.com', 'p@ssword', 'Can Tho', '1994-01-05', '0978123456', 2, 34000),
('Nguyen Van N', 'nguyenn@gmail.com', 'password123', 'Ha Long', '1989-12-30', '0912345678', NULL, 46000),
('Tran Van P', 'tranp@gmail.com', 'myp@ss', 'Hai Phong', '1990-05-25', '0934567890', 1, 39000),
('Pham Thi Q', 'phamq@gmail.com', 'secretp@ss', 'Da Nang', '1993-09-18', '0967890123', 3, 33000);
INSERT INTO DonHang VALUES
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
(),
();
-- Bổ sung dữ liệu vào bảng HoaDon
INSERT INTO HoaDon VALUES
(),
(),
(),
(),
(),
(),
(),
(),
(),