Lỗi chạy sai insert

use master
go
create database QLSV
on primary(
	name = 'QLSV',
	filename = 'E:\QLSV.mdf',
	size = 3 MB,
	maxsize = 10 MB,
	filegrowth = 2MB
	)
log on(
	name = 'QLSV.ldf',
	filename = 'E:\QLSV.ldf',
	size =1 MB,
	maxsize = 5MB,
	filegrowth = 10%
	)
go
use QLSV
go
create table Khoa(
	maKhoa nchar(10) not null primary key,
	tenKhoa nvarchar(20) not null,
	soluongsv int not null
)
create table Lop(
	maLop nchar(10) not null primary key,
	maKhoa nchar(10) not null,
	tenLop nvarchar(20) not null,
	phong nvarchar(20),
	soluong int not null,
	constraint FK_Lop_Khoa foreign key(maKhoa) 
				references Khoa(maKhoa)
	
)
insert into Khoa values('K01',N'Kế toán',150)
insert into Khoa values('K02',N'Điện tử',200)
insert into Khoa values('K03',N'Cơ khí',280)

insert into Lop values('L01','K02',N'Điện tử 1',N'Phát triển',50)
insert into Lop values('L02','K01',N'Kế toán 3',N'Học tập',65)
insert into Lop values('L03','K03',N'Cơ khí 3',N'Sáng tạo',75)

------------2------------

ALTER trigger trg_insert
on Lop
for insert
AS BEGIN
	declare @tl nchar(10)
	set @tl = (SELECT maLop from inserted)
	IF EXISTS(select * from Lop where maLop=@tl)
		begin
			raiserror(N'Đã tồn tại lớp',16,1)
			rollback TRAN
			RETURN
		END
     ELSE
       BEGIN
	       DECLARE @slsv INT,@mak NCHAR(10)
	       SELECT @slsv=soluong FROM inserted
	       SELECT @mak=maKhoa FROM inserted
         	UPDATE Khoa SET soluongsv=soluongsv+@slsv WHERE maKhoa=@mak
       END
END

–>test:

insert into dbo.Lop values('J08','K02',N'Điện tử 1',N'Phát ttt',10)
SELECT*FROM dbo.Lop

anh chị xem giúp e,e không hiểu sao trigger nó toàn hiện lỗi raiseorror dù insert chạy đúng

Ủa, sao lại là @tl = maLop trong bảng Lop có cột @tl à?

2 Likes

tl là biến được tạo, e có đổi ngược lại maLop=@tl thì nó vẫn vậy

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

Trong Alter trigger t-SQL document:

AFTER
Specifies that the trigger is fired only after the triggering SQL statement is executed successfully. All referential cascade actions and constraint checks also must have been successful before this trigger fires.
AFTER is the default, if only the FOR keyword is specified.

Trigger của cậu là for insert, nên nó sẽ thực thi sau khi insert được thực thi -> hiển nhiên record đó đã tồn tại trước khi trigger fires.

Nếu tớ không nhầm, SQL server không support before insert như PostgreSQL hay Oracle SQL, nên để code kia của cậu chạy, cậu buộc phải hack 1 chút với INSTEAD OF INSERT: thay vì insert, cậu sẽ update, rồi sau đó insert bản ghi mới.

Cũng từ doc nói trên, về INSTEAD OF

INSTEAD OF
Specifies that the DML trigger is executed instead of the triggering SQL statement, therefore, overriding the actions of the triggering statements. INSTEAD OF cannot be specified for DDL or logon triggers.

3 Likes

nếu dùng instead of thì không chèn được vào bảng cần insert

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

Có vẻ như cậu chưa hiểu tớ định nói gì rồi :slight_smile:
Lúc nãy tớ có nói:

Tớ sẽ đưa ra 1 ví dụ để giải thích cho điều đó.
Hiện tại trigger của cậu làm việc như thế này:

  1. Insert record vào bảng Lop
  2. Khi sự kiện insert trên xảy ra, trigger được kích hoạt
    1.1 Cậu tìm kiếm bản ghi đã được insert
    1.2 Nếu bản ghi đó tồn tại, tung exception và rollback transaction (không insert nữa)
    1.3 Nếu bản ghi đó không tồn tại, tăng số lượng sinh viên trong bảng Khoa

Vì trigger của cậu fire sau khi sự kiện insert đã xảy ra, cậu cần hack 1 chút với INSTEAD OF INSERT

  1. Insert record vào bảng Lop
  2. Trước khi sự kiện insert trên xảy ra (do INSTEAD OF INSERT), override lại thao tác insert
    1.1 Cậu tìm kiếm bản ghi đã được insert
    1.2 Nếu bản ghi đó tồn tại, tung exception và rollback transaction (không insert nữa)
    1.3 Nếu bản ghi đó không tồn tại, tăng số lượng sinh viên trong bảng Khoa
    1.4 Insert bản ghi sẽ được insert vào bảng Lop (tớ nghĩ đoạn này không khó, khi cậu đã có thông tin insert khi trigger fires)

Như vậy, cậu đã mimic lại được BEFORE INSERT trigger bên Oracle SQL/PostgreSQL rồi :slight_smile:

Hope it helps!


P/s: tớ có góp ý cho cậu, thay vì nói:

nếu dùng instead of thì không chèn được vào bảng cần insert

1 cách lửng lơ như vậy, cậu nên nói có chủ ngữ:

Tớ nghĩ nếu dùng instead of thì không chèn được vào bảng cần insert. Không biết tớ hiểu như vậy có đúng không?

Hoặc cậu có thể dùng tiếng Nhật, bên đó không cần chủ ngữ khi nói :stuck_out_tongue:

3 Likes

Ồ, thế thì tớ thật sự xin lỗi :v , tớ không biết nói thế là mất lịch sự :face_with_hand_over_mouth:

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?