检查记录是否存在多个条件,否则插入SQL Server存储过程

时间:2017-10-01 10:34:23

标签: c# sql sql-server stored-procedures ado

我已经编写了如下程序来检查日期和老虎机或教室组合的记录或(特定标准和分区),如下所示。

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

但它似乎不起作用。请允许任何人建议如何在插入之前检查多个条件,如果有其他帮助或是否有其他方法来解决此问题?

2 个答案:

答案 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;