# Đề 2: Kiểm tra SQL - .NET API - JS
1. Khởi tạo cơ sở dữ `StudentManagement` liệu như sau:
- Bảng `Students` bao gồm thông tin sinh viên:
- `Id int pk tự tăng`
- `RollNumber nvarchar(50) not null`
- `FullName nvarchar(200) not null`
- `PhoneNumber nvarchar(50)`
- `EmailAddress nvarchar(200)`
- `Address nvarchar(100)`
- `Average decimal(18,1) default 0`
- Bảng `Marks` bao gồm thông tin điểm của môn học:
- `Id int pk tự tăng`
- `StudentId int FK đến bảng Student`
- `SubjectsName nvarchar(100) not null`
- `Score decimal(18,1) not null default 0, yêu cầu Score >=0 và <= 10`
- `Factor decimal(18,1) default 1, yêu cầu Factor >=1 và <= 3`
2. Thêm dữ liệu mẫu về điểm theo yêu cầu như sau:
```sql
insert into Students (RollNumber, FullName, PhoneNumber, EmailAddress, Address, Average) values ('Quillan', 'Quillan Casado', '617-879-6106', 'qcasado0@tmall.com', '4th Floor', 0);
insert into Students (RollNumber, FullName, PhoneNumber, EmailAddress, Address, Average) values ('Dodie', 'Dodie Linke', '178-687-9328', 'dlinke1@apache.org', 'Suite 63', 0);
insert into Students (RollNumber, FullName, PhoneNumber, EmailAddress, Address, Average) values ('Darcey', 'Darcey Lambrechts', '314-566-4082', 'dlambrechts2@sina.com.cn', 'PO Box 35470', 0);
insert into Students (RollNumber, FullName, PhoneNumber, EmailAddress, Address, Average) values ('Ediva', 'Ediva Macer', '481-857-3948', 'emacer3@yandex.ru', 'Apt 275', 0);
insert into Students (RollNumber, FullName, PhoneNumber, EmailAddress, Address, Average) values ('Mirna', 'Mirna Stollberger', '954-973-1998', 'mstollberger4@umich.edu', 'PO Box 50594', 0);
```
```sql
insert into Marks (StudentId, SubjectsName, Score, Factor) values (2, 'Literature', 8.3, 1.8);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (2, 'Math', 18.9, 1.8);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (3, 'Geography', 16.9, 2.4);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (4, 'Math', 8.5, 1.9);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (2, 'Geography', 10.4, 1.4);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (3, 'Math', 13.3, 1.1);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (4, 'Geography', 8.5, 1.8);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (1, 'Literature', 4.3, 1.9);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (5, 'Geography', 2.9, 2.7);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (5, 'Geography', 5.7, 2.8);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (4, 'Chemistry', 16.8, 1.1);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (3, 'Literature', 8.7, 2.9);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (1, 'Chemistry', 17.8, 1.4);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (1, 'Math', 14.7, 2.2);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (5, 'Literature', 10.9, 2.1);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (3, 'Literature', 6.7, 2.6);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (2, 'Geography', 17.7, 2.6);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (1, 'Geography', 5.0, 1.8);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (3, 'Math', 13.3, 2.6);
insert into Marks (StudentId, SubjectsName, Score, Factor) values (5, 'Math', 14.1, 1.4);
```
3. Viết StoreProcedure `usp_SaveStudents`, parameters `_id, _rollNumber, _fullName, _phoneNumber, _emailAddress, _address`. Tiến hành thêm mới (Nếu `_id = 0`) hoặc cập nhật (Nếu `_id > 0 `) một `Student`
8. Viết Trigger `trigger_UpdateAverage` khởi tạo trigger, khi có thay đổi (Thêm/Sửa/Xóa) điểm của học sinh nào thì cập nhật `Average` trong bảng `Students` của học sinh đó.
9. Tạo một WebService sử dụng API với .NET (MVC hoặc API), tạo Controller có tên `ApiStudentsController`. Trong controller này có các action:
- `ViewStudents`: Nhận vào tham số `_keyword, _pageIndex, _pageSize` từ client và gọi đến store `usp_ViewStudents` để lấy dữ liệu. Dữ liệu trả ra dưới dạng JSON
- `SaveStudent`: Nhận vào tham số `_id, _rollNumber, _fullName, _phoneNumber, _emailAddress, _address` từ client và khởi tạo/cập nhật `Students`.
- `DeleteStudent`: Nhận vào tham số `_id` từ client và xóa bản ghi tương ứng.
- `UpdateMarks`: Nhận vào tham số `_studentId kiểu int và _marks là 1 array JSON có các property giống như bảng marks bên trên` từ client và cập nhật điểm cho bản ghi tương ứng. Lưu ý khi cập nhật xong kiểm tra điểm trung bình xem trigger có chạy không.
10. Tạo một trang `index.html` có cấu trúc như sau:
- Gọi vào API để lấy ra dữ liệu dạng bảng và phân trang. Khi ấn nút tìm kiếm cũng sẽ tìm kiếm ra dữ liệu tương ứng (Gọi đến action `ViewStudents` bên trên)

- Khi click vào nút `Create Student` sẽ bật ra modal để thêm mới dữ liệu khi ấn `Save` (gọi đến action `SaveStudent` bên trên). Dữ liệu thay đổi ngay trên trang.

- Khi click nút `Update` sẽ bật ra modal, load dữ liệu của `Student` tương ứng và cho phép save khi ấn `Save` (gọi đến action `SaveStudent` bên trên). Dữ liệu thay đổi ngay trên trang.

- Khi click vào nút `UpdateMark`, nếu chưa có điểm nào thì hiển thị ô điểm trống và tiến hành thêm điểm. Nếu ấn vào nút `Add Mark` thì in thêm một dòng như dòng mẫu (nếu không có điểm cho hiển thị 1 dòng). Nếu ấn vào dấu X thì xóa dòng đó đi. Ấn `Save` (gọi đến action `UpdateMarks` bên trên) sẽ lưu dữ liệu vào database.

- Khi click vào nút `UpdateMark`, nếu có điểm rồi thì load toàn bộ danh sách điểm của học viên, sau đó có thể tiến hành thêm/sửa/xóa điểm. Ấn `Save` (gọi đến action `UpdateMarks` bên trên) sẽ lưu dữ liệu vào database.

11. Yêu cầu bổ sung:
- Nếu thực hiện thành công hay thất bại thì alert thành công/thất bại.
- Không tải lại trang. Nên sử dụng SPA như AngularJS hoặc VueJS/ReactJS. Nếu sử dụng JS thuần hoặc JQUERY thì phải gọi AJAX đến API