在SQL Server存储过程

时间:2017-04-03 13:45:14

标签: sql stored-procedures sql-server-2012

我正在研究我的最后一年项目,这是一个学校管理系统,这个项目有很多任务,但我现在正在研究考勤模块,我创建了一个包含四列的sql server表:

  1. 学生姓名
  2. 班级名称
  3. 出勤状态(列名称为“状态”)
  4. 日期(出席日期)
  5. 然后我创建了一个存储过程。该存储过程将获取学生姓名,班级名称和出勤状态作为参数,然后将其添加到考勤表中,该表显示学生是否在指定日期或缺席, 日期列的默认值为getDate()

    存储过程首先检查学生出勤是否已经存在于当前日期的表中,然后更改出勤状态列值而不是添加新行,如果当前日期没有学生出勤,则存储程序将添加新行,

    BUT ......

    我的程序没有按预期工作,当我第一次传递参数时,它会添加新行,当我再次传递相同的参数时,它应该替换考勤状态列,但它会再添加一个新行。

    但第三次,当我传递相同的参数,然后它正常工作并替换状态列值,所以在这种情况下,我有2行为同一个学生,但我只需要一行。

    请指导我存储过程中的问题 - 这是代码:

    create procedure spAttend_Stu
        @Name nvarchar(200),
        @C_Name nvarchar(50),
        @Status nvarchar(50)
    as
    begin
        if ((select count(*) 
             from tbl_Attend_Stu 
             where Student_Name = @Name 
               and Date = (select convert(date, getdate()))) > 1)
           update tbl_Attend_Stu 
           set [Status] = @Status 
           where [Date] = (select convert(date, getdate()))
        else
           insert into tbl_Attend_Stu (Student_Name, Class_Name, Status)
           values (@Name, @C_Name, @Status)
    end
    

    编辑:

    这是我的表定义..请看这个截图:

    Table structure

    我将此值作为示例传递

    spAttend_Stu 'Ammar', 'BSCS', 'Absent'
    

    我再次运行相同的查询,但结果不符合预期

    查看此屏幕截图,例如执行

    example execution

1 个答案:

答案 0 :(得分:1)

如果您发布了tbl_Attend_Stu的架构构造函数语法,那将会很有帮助,因此我们可以看到字段Date及其默认值。但是,有一些初步的想法供您检查(注意:没有看到传入的内容的示例,以及表格中的值很难确定):

  1. 也许@Name的价值并不是您在传递到SP时的预期。如果值变化,即使是略微变化,那么第一个IF语句逻辑将找不到学生,并且将发生另一个插入。一个可能的解决方法是确保@Name@C_Name变量正确修剪;如果他们被空格传递给SP,那么它可能是你的罪魁祸首。
  2. 如果Date的默认值配置设置不正确,则在调用INSERT语句时不会插入日期。尝试在Date语句中明确地将INSERT设置为CONVERT(DATE, GETDATE()),看看这是否能满足您的期望。
  3. 我在代码中发现了其他问题。例如,您在UPDATE语句逻辑中缺少第二个条件,只更新特定学生的行。您现在拥有它的方式将更新表中每一行的Date字段。
  4. 我在这里重写了你的逻辑以使它更具可读性,并修复了我上面提到的错误,以及其他小的语法错别字:

    create procedure spAttend_Stu
    @Name nvarchar(200),
    @C_Name nvarchar(50),
    @Status nvarchar(50)
    AS
    BEGIN
    
    IF
    ( 
        (SELECT COUNT(*) 
         FROM   tbl_Attend_Stu 
         WHERE  Student_Name = @Name 
            AND [Date] = CONVERT(DATE, GETDATE()) 
        )
        >= 1
    )
        UPDATE tbl_Attend_Stu 
        SET [Status] = @Status 
        WHERE   Student_Name = @Name
            AND [Date] = CONVERT(DATE, GETDATE())
    
    ELSE
    
        INSERT INTO tbl_Attend_Stu
            (Student_Name, Class_Name, Status)
        VALUES
            (RTRIM(LTRIM(@Name)), RTRIM(LTRIM(@C_Name)), @Status)
    
    END