sql - (SQL Server 触发器)无法绑定多部分标识符
问题描述
我尝试在 TAKES 表上创建触发器,但收到 4 个类似错误:
无法绑定多部分标识符“Inserted.course_id”。
无法绑定多部分标识符“Inserted.sec”。
无法绑定多部分标识符“Inserted.semester”。
无法绑定多部分标识符“Inserted.year”。
这是我的代码:
CREATE TRIGGER check_capacity ON takes FOR INSERT
AS
DECLARE @max_capacity INT;
DECLARE @current_capacity INT;
DECLARE @course_id VARCHAR;
DECLARE @sec_id VARCHAR;
DECLARE @semester VARCHAR;
DECLARE @year_ INT;
BEGIN
SET @course_id = inserted.course_id;
SET @sec_id = inserted.sec;
SET @semester = inserted.semester;
SET @year_ = inserted.year;
SET @max_capacity = dbo.get_max_capacity(@course_id,
@sec_id,
@semester,
@year_);
SET @current_capacity = dbo.get_current_capacity(@course_id,
@sec_id,
@semester,
@year_);
IF ( @max_capacity > @current_capacity ) BEGIN
print 'Insert successfully';
END
ELSE BEGIN
print 'Max capacity ' + isnull(@max_capacity, '');
print 'Current capacity ' + isnull(@current_capacity, '');
print 'The classroom is full! Choose the others';
END
END
解决方案
此触发器有许多主要缺陷:
- 不考虑插入多个(或零个)行
PRINT
不阻止事务发生,您需要THROW
. 请注意,您不应该ROLLBACK
在触发器中手动操作,抛出异常将为您执行此操作- 使用标量函数,这对性能非常不利。(我无法解决这个问题,因为我不知道他们在做什么)
- 如果@max_capacity等于@current_capacity 那么它也会失败,我认为这不应该发生
- 使用
varchar
没有长度是错误的,varchar(1)
在某些情况下默认为
CREATE TRIGGER check_capacity ON takes FOR INSERT
AS
DECLARE @max_capacity INT;
DECLARE @current_capacity INT;
IF (EXISTS (SELECT 1
FROM inserted i
WHERE dbo.get_max_capacity(i.course_id, i.sec_id, i.semester, i.year) <
dbo.get_current_capacity(i.course_id, i.sec_id, i.semester, i.year)
))
THROW 70000, N'The classroom is full! Choose the others', 0;
GO
如果您希望在错误消息中显示确切的数字,您可以这样做,但它只会显示第一个不合格行的结果:
CREATE TRIGGER check_capacity ON takes FOR INSERT
AS
DECLARE @max_capacity INT;
DECLARE @current_capacity INT;
SELECT TOP (1)
@max_capacity = v.max_capacity,
@current_capacity = v.current_capacity
FROM inserted i
CROSS APPLY (VALUES
(dbo.get_max_capacity(i.course_id, i.sec_id, i.semester, i.year),
dbo.get_current_capacity(i.course_id, i.sec_id, i.semester, i.year))
) v(max_capacity, current_capacity)
WHERE v.max_capacity < v.current_capacity;
IF (@@ROWCOUNT > 0)
BEGIN
DECLARE @msg nvarchar(150) = CONCAT('Max capacity ', @max_capacity, '
Current capacity ', @current_capacity, '
The classroom is full! Choose the others');
THROW 70000, @msg, 0;
END;
GO
推荐阅读
- php - 在 Godaddy 上的 Cronjob 上安排一个简单的 php 文件
- mikro-orm - Mikro ORM:插入集合的最佳方法是什么
- javascript - 如何在数据库查询中正确使用异步等待
- angular - Angular中的条件验证问题
- swift - 我需要帮助在 iOS Amplify 库与 AWSMobileClient 之间做出选择以使用 Apple 登录
- python - 如何将列中的元素拆分为python中的更多列
- javascript - 如何在沙盒 iframe 上允许 document.domain?
- javascript - 我的 heroku 应用程序没有在 heroku 上获得 postgresDB
- python - Django:ConnectionResetError:[Errno 54]
- android - Android Wear:无法将 DataItem 从可穿戴设备发送到手机