我是编程新手。我正在尝试自学SQL。我创建了一个包含客户,租赁和库存表的视频商店数据库。我在网上看例子试图学习SQL,所以请善待。我想让这个触发器阻止一个人同时租用同一部电影。我一直在阅读触发器,并希望获得以下代码的一些帮助。
我在最后一个END上遇到语法错误,RAISEERROR上的语法错误和INSERTED。我还在收到消息"触发多部分标识符无法绑定"在i.Rental.rentNum上插入i;
非常感谢任何帮助!
CREATE TRIGGER
insteadOFInsert ON Rental
INSTEAD OF INSERT
AS
DECLARE @rentNum int, @action varchar(60)
SELECT @Rent_rentNum=i.Rental.rentNum inserted i;
SET @action='stop rental trigger.'
@Rent_rentNum=(SELECT rentNum FROM inserted;
BEGIN
BEGIN TRAN
SET NOCOUNT ON
IF (@RENT_rentNum=Rental.rentNum)
BEGIN
RAISEERROR ('You cannot rent the same move twice');
ROLLBACK
END
ELSE
BEGIN
INSERT INTO
Rental(rentNum)
VALUES
(@rentNum)
INSERT INTO
Rent values (rentNum);
COMMIT
PRINT 'Updated'
END
END
答案 0 :(得分:0)
您从第二个插入语句中缺少values
。试试这个
INSERT INTO Rent values (@rentNum);
<强> [编辑] 强>
DECLARE @Rent_rentNum int
SET @Rent_rentNum = (SELECT rentNum FROM inserted);
并且还匹配每个打开和关闭BEGIN
&amp; END
答案 1 :(得分:0)
你的第一个SELECT在“插入”之前缺少一个FROM。
答案 2 :(得分:0)
您的触发器有几个基本缺陷:
请 永远不要 在触发器中使用BEGIN TRAN
!触发器在导致触发的语句的上下文中运行,因此在事务的上下文中已经
你需要知道触发器将被称为每个语句 - 每行不会一次!因此,如果您的INSERT
语句插入10行,则触发器会被触发一次,而Inserted
伪表将包含 10行数据 - 其中您认为会在您的陈述中选择一个
SELECT rentNum FROM inserted;
他们中的一个会做 - 一个或多或少随机 - 而另外9个将被忽略。
所以基本上,你需要完全重写你的触发器:
CREATE TRIGGER insteadOFInsert
ON dbo.Rental
AFTER INSERT
AS
// if any one of the rows inserted already exists in the Rental table -> abort
IF EXISTS (SELECT * FROM dbo.Rental WHERE RentNum IN (SELECT RentNum FROM Inserted))
BEGIN
RAISEERROR ('You cannot rent the same move twice');
ROLLBACK
END
你没有解释为什么你选择使用INSTEAD OF INSERT
触发器 - 我真的没有看到任何好的理由,所以我选择这样做{{1}触发器(它只是简单地写这些)