我已经编写了如下程序来检查日期和老虎机或教室组合的记录或(特定标准和分区),如下所示。
ALTER PROCEDURE [dbo].[procCreateSchedule]
(@classId INT,
@dayId INT,
@slotId INT,
@standardId INT,
@divisionId INT,
@subjectId INT,
@teacherId INT)
AS
BEGIN
IF NOT EXISTS (SELECT * FROM schedules_test
WHERE day = @dayId
AND slot = @slotId
AND standard = @standardId
AND division = @divisionId)
ELSE
IF NOT EXISTS (SELECT * FROM schedules_test
WHERE day = @dayId
AND slot = @slotId
AND teacherId = @teacherId)
ELSE
IF NOT EXISTS (SELECT * FROM schedules_test
WHERE day = @dayId
AND slot = @slotId
AND classroom = @classId)
ELSE
BEGIN
INSERT INTO schedules_test (classroom, day, slot, standard, division, subject, teacherId)
VALUES (@classId, @dayId, @slotId, @standardId, @divisionId, @subjectId, @teacherId)
END
END
但它似乎不起作用。请允许任何人建议如何在插入之前检查多个条件,如果有其他帮助或是否有其他方法来解决此问题?
答案 0 :(得分:1)
您可以在一个WHERE
声明中将所有条件转换为一个SELECT
子句:
IF EXISTS (
SELECT * FROM scheduled_tests
WHERE day=@dayId AND slot=@slotId AND
(classroom=@classId OR teacherId OR standard=@standardId AND division=@divisionId)
)
....
但实际上,如果可以,请不要编写存储过程。将此逻辑添加到您的C#代码中,将来每个人阅读代码都会更容易维护。
答案 1 :(得分:1)
请勿在应用程序层检查此项。您受竞争条件限制 - 两个不同的线程插入相同的数据。两者都可以成功。
而是创建唯一索引,以便数据库验证数据。唯一索引应该是:
schedules_test(day, slot, standard, division)
schedules_test(day, slot, teacherid)
schedules_test(day, slot, classid)
(注意:键的顺序无关紧要。)
然后,存储过程的主体可以使用try
/ catch
:
begin try
insert into schedules_test(classroom, day, slot, standard, division, subject, teacherId)
values (@classId, @dayId, @slotId, @standardId, @divisionId, @subjectId, @teacherId);
end try
begin catch
. . .
end catch;