anh ơi nhưng bài có cho là phải dung ROLLBACK TRAN vào trigger để kiểm tra anh ak
Hướng dẫn làm bài tập hệ quản trị cơ sở dữ liệu
Roll back thì có 2 cách. Một là dùng code thực hiện query trong DB. Nếu ổn thì commit, nếu không ổn thì không commit. (tương tự OK và CANCEL)
Hai là nếu bắt buộc dùng trigger thì:
SET XACT_ABORT ON
BEGIN TRAN
BEGIN TRY
-- query 1
-- query 2
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
RAISERROR('Error', 16, 1)
END CATCH
ROLLBACK TRAN(transaction) dùng để hủy thao tác insert/update/delete mà e vừa thực hiện. Thật ra trigger dùng để tự động rằng buộc dữ liệu trong SQL khi người dùng “tác động” lên dữ liệu nhằm bảo vệ dữ liệu. Ví dụ năm sinh của 1 người không thể <0. Em tạo 1 trigger để khi người dùng nhập năm sinh hay cập nhật năm sinh mà gán =0, thì trigger sẽ phát hiện và e cho nó rollback tran, tức là hủy thác tác nhập hay cập nhật năm sinh ấy. Vì thực ra, khi e insert/update/delete thì dữ liệu đã đc ghi vào các bảng inserted/updated/deleted (cứ coi như là bảng tạm), nếu mọi việc ổn thỏa, nó sẽ đc lưu xuống csdl thật, nếu k ổn thì sẽ bị hủy.
anh xem câu 2 của em nhé
--TRIGGER
--2
--Hãy viết trigger để tự động kiểm tra khi Insert một bản ghi vào bảng Dangky nếu
--Hocky>10 hoặc <0 thì không được phép Insert (dùng lệnh ROLLBACK TRAN)
CREATE TRIGGER TR_INSERT_DangKy
ON DangKy
FOR INSERT
AS
DECLARE @MaSV varchar(10)
DECLARE @MaMon varchar(10)
DECLARE @HocKy smallint
SELECT @MaSV=MaSV,@MaMon=MaMon,@HocKy=HocKy FROM DangKy
IF (@HocKy>10 or @HocKy<0)
ROLLBACK TRAN
else
PRINT'Thêm thành công'
câu function của e, hàm tính tuổi có vẻ k ổn nhé, tính tuổi thì chỉ cần e truyền vào năm sinh, lấy năm hiện tại trừ đi là dc thôi.
CREATE FUNCTION F_tinhtuoi (@NamSinh smalldatetime)
RETURNS INT
AS
BEGIN
DECLARE @tuoi INT
SET @tuoi= YEAR(GETDATE())-YEAR(@NamSinh)
RETURN @tuoi
END
go
phần này em chưa đụng nhiều nên em không hiểu code ảnh lắm , nhưng em biết try catch là dùng để bắt lỗi … vì đây là kỹ thuật mới với em với lại em không biết COMMIT dùng để làm gì hả anh , em giờ mới biết
ôi đúng rồi !!! anh làm em sáng dạ quá em làm phức tạp mà không đúng … hixx
E SỬA LẠI THÀNH
SELECT @MaSV=MaSV,@MaMon=MaMon,@HocKy=HocKy FROM inserted (chứ k fai DangKy)
Như a đã nói ở trên, trigger thì chỉ liên quan đến các bảng inserted, deleted, updated tuognw ứng với các thao tác.
may quá có anh em sửa được rồi hi…
Anh ơi câu 3 em làm xong rồi
CREATE TRIGGER TR_CAU3
ON DangKy
FOR INSERT
AS
DECLARE @MaSV varchar(10)
DECLARE @MaMon varchar(10)
DECLARE @HocKy smallint
SELECT @MaSV=MaSV,@MaMon=MaMon,@HocKy=HocKy FROM INSERTED
IF NOT EXISTS (SELECT @MaMon FROM DangKy WHERE @MaMon=MaMon )
ROLLBACK TRAN
ELSE
PRINT'Thêm thành công'
câu 5 : a ơi em tấy câu này em dùng contro khong tự tin mắc nhiều lỗi quá
--Hãy viết trigger để tự động xóa tất cả Sinh viên của 1 lớp khi Delete một bản ghi ở bảng
--Lop tương ứng với lớp đó.
CREATE TRIGGER CAU5
ON LOP
FOR DELETE
AS
BEGIN
DECLARE @MaLop varchar(10)
DECLARE @MaSV varchar(10)
DECLARE contro CURSOR FOR
SELECT MaSV,TenSV FROM DELETED
WHERE Lop.MaLop=@MaLop
OPEN contro
FETCH NEXT FROM contro INTO @MaSV
WHILE @@FETCH_STATUS=0
BEGIN
DELETE MaSV WHERE MaLop=@MaLop
FETCH NEXT FROM contro INTO @MaSV
END
CLOSE contro
DEALLOCATE contro
END
CÂU 6:
--Hãy viết trigger để tự động cập nhật lại Mã lớp của tất cả Sinh viên của 1 lớp khi Update
--lại mã lớp của bản ghi tương ứng với lớp đó ở bảng Lop.
CREATE TRIGGER CAU6
ON Lop
FOR UPDATE
AS
IF UPDATE (MaLop)
BEGIN
DECLARE @MaLop varchar(10)
DECLARE @MaSV varchar(10)
DECLARE contro CURSOR FOR
SELECT inserted.MaLop
FROM INSERTED INNER JOIN DELETED
ON INSERTED.MaLop=DELETED.MaLop
OPEN contro
FETCH NEXT FROM contro INTO @MaLop,@MaSV
WHILE @@FETCH_STATUS=0
BEGIN
UPDATE SV.MaLop SET MaLop=@MaLop
WHERE Lop.MaLop=@MaLop
FETCH NEXT FROM contro INTO @MaSV,@MaLop
END
CLOSE contro
DEALLOCATE contro
END
CAU 7 cau em day ak
--Hãy viết trigger để tự động cập nhật lại Số SV (cộng thêm 1) của 1 lớp ở bảng Lớp khi
--thêm 1 sinh viên của lớp đó vào bảng Sinhvien. Tương tự viết Trigger cho trường hợp xóa 1 SV
--khỏi bảng Sinhvien.
CREATE TRIGGER CAU7
ON Lop
FOR UPDATE
AS
BEGIN
DECLARE @MaSV varchar(10)
DECLARE @SoSV int
DECLARE @MaLop varchar(10)
if( SELECT COUNT( INSERTED.MaSV ) FROM SV
WHERE MaSV=@MaSV AND MaLop=@MaLop)=1
update Lop
SET SoSV=SoSV+1
ELSE if( SELECT COUNT( DELETED.MaSV ) FROM SV
WHERE MaSV=@MaSV AND MaLop=@MaLop)=1
update Lop
SET SoSV=SoSV-1
END
em có ý tưởng thế này thời những lỗi lam không hiểu sao nữa mong anh test hộ em với
chắc không minh mẫn làm thêm được nữa…hixx
ok e, có j trưa hoặ tối a tranh thủ a xem nhé
Mấy cái này thật tình là Đạt quên sạch trơn luôn, ở đây toàn cao thủ không. Hồi trước học chuyên ngành HTTT mà giờ mấy món này sau khi đi làm 4 năm quên sạch trơn.
Vâng cảm ơn mấy anh !!!
Thật ra mấy cái trigger này đơn giản. Mình thấy @Is2IT đưa link có hết trong đó rồi. Kèm theo google xem nhiều example thì làm hết bài này trong 1 buổi.
Câu 3 a ngĩ thế này mới đúng.
CREATE TRIGGER TR_CAU3
ON DangKy
FOR INSERT
AS
IF NOT EXISTS (SELECT * FROM MonHoc mh, inserted i WHERE i.MaMon=mh.MaMon)
begin
PRINT N'Mon hocj khong ton tai'
ROLLBACK TRAN
end
ELSE
begin
PRINT N'Thêm thành công'
end
Câu này có thể em sẽ k test dc, vì vốn dĩ khi e insert 1 mã môn học k tồn tại vào trong đăn ký, nó đã vi phạm rằng buộc khóa ngoại, nên nó sẽ la làng lên trước khi trigger của e dc la làng.
@vanhop , @btm nói đúng đó e, mấy bài này là những bài cơ bản nhất, sau này e học sẽ gặp những bài phức tạp hơn nhiều, e cứ chịu khó làm hết mấy bài cơ bản, rồi từ từ sẽ làm dc những bài phức tạp hơn. Ngày trước a cũng chỉ được học sâu hơn chút thôi, giờ ra không đụng đến nến cũng không khá hơn ngày trước là bao. Giúp dc đến đâu a sẽ giúp. Hơn nữa, trong các lệnh if, else
e nên để cặp begin,end
giống như if, else
trong C/C++ nên để trong cặp {}