【问题标题】:SQL Server IF NOT EXISTS Usage?SQL Server IF NOT EXISTS 用法?
【发布时间】:2010-11-13 14:20:15
【问题描述】:

好的,我的架构是这样的:

表:Timesheet_Hours

列:

  • Timesheet_Id(PK,int)
  • Staff_Id (int)
  • BookedHours (int)
  • Posted_Flag(布尔值)

这是一个极其简化的表格版本,但仅用于本说明的目的。假设一个人只能有一个时间表记录。

我正在尝试将记录添加到另一个名为 WorkLog 的表中。这里的每条记录都有一个与之关联的时间。当该表更新时,我也想更新 Timesheet_Hours。

在我更新 Timesheet_Hours 之前,我想首先检查相关的 Timesheets 是否尚未发布,然后我想首先检查是否确实有要更新的记录。

if 语句的第一部分检查时间表是否尚未发布,它工作正常。问题是第二部分。它正在检查它要更新的记录是否已经存在。问题是它总是引发错误。

注意:下面的代码是从工作日志表上的更新、插入和删除触发器运行的存储过程中提取的。 @PersonID 是该表的参数之一。如果我注释掉该语句的第二部分,存储过程就可以正常工作。

IF EXISTS
    (
    SELECT 1
    FROM Timesheet_Hours
    WHERE Posted_Flag = 1
    AND Staff_Id = @PersonID
    )

    BEGIN
        RAISERROR('Timesheets have already been posted!', 16, 1)
        ROLLBACK TRAN
    END
ELSE
    IF NOT EXISTS
        (
        SELECT 1
        FROM Timesheet_Hours
        WHERE Staff_Id = @PersonID
        )

        BEGIN
            RAISERROR('Default list has not been loaded!', 16, 1)
            ROLLBACK TRAN
        END

【问题讨论】:

  • 1 是 Timesheet_Hours 表中列的名称吗?
  • 不,不是。当我使用 EXISTS 时,我只是在遵循我认为使用 EXISTS 进行子查询的标准做法。
  • 1 在这种情况下只是一个常数。他关心的只是返回一行,而不是任何列的值。使用常量通常比使用 * 或特定列列表更快。
  • 'if not exists()' 工作得很好。您对它的使用可能会受到质疑。您可能希望将问题命名为“如果不存在,我该如何使用 SQL Server?”而是。
  • 完成,根据您的建议,正义。

标签: sql sql-server stored-procedures


【解决方案1】:

您是否验证过实际上有一行 Staff_Id = @PersonID?假设该行存在,您发布的内容在测试脚本中运行良好。如果注释掉插入语句,则会引发错误。

set nocount on

create table Timesheet_Hours (Staff_Id int, BookedHours int, Posted_Flag bit)

insert into Timesheet_Hours (Staff_Id, BookedHours, Posted_Flag) values (1, 5.5, 0)

declare @PersonID int
set @PersonID = 1

IF EXISTS    
    (
    SELECT 1    
    FROM Timesheet_Hours    
    WHERE Posted_Flag = 1    
        AND Staff_Id = @PersonID    
    )    
    BEGIN
        RAISERROR('Timesheets have already been posted!', 16, 1)
        ROLLBACK TRAN
    END
ELSE
    IF NOT EXISTS
        (
        SELECT 1
        FROM Timesheet_Hours
        WHERE Staff_Id = @PersonID
        )
        BEGIN
            RAISERROR('Default list has not been loaded!', 16, 1)
            ROLLBACK TRAN
        END
    ELSE
        print 'No problems here'

drop table Timesheet_Hours

【讨论】:

  • 谢谢伙计。原来我没有从 INSERT 触发器传递正确的 PersonID。这让我很困惑,因为它正在使用 UPDATE 和 DELETE 触发器,但我没想到要检查参数。
猜你喜欢
  • 1970-01-01
  • 2011-09-25
  • 2016-04-19
  • 2021-08-29
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 2019-05-18
相关资源
最近更新 更多