SQL Server-IF EXISTS同时执行TRUE分支和FALSE分支



我需要检查表中是否存在现有记录(用于员工评估)。如果存在这样的记录,则查询必须获取该员工的最新条目,并计算下一次评估的下一个开始日期和结束日期。如果不存在这样的记录,则查询必须应用不同的逻辑,并为第一次评估计算新的开始日期和结束日期(从当前日期开始倒计时)。

为了做到这一点,我在SQL Server中使用了IF EXISTS表达式,但似乎如果我对开始日期和结束日期变量保持相同的名称,SQL就会覆盖它们(因此会按顺序执行分支,而不是选择其中一个)。所以我声明了两组变量来克服这个问题。然而,SQL Server似乎一直在计算每种情况的开始日期和结束日期(EXISTS和NOT EXISTS)。我知道这一点是因为我要求它打印4个变量,所有变量都打印了不同的值。

以下是我(现在)的4个变量的声明:

    IF EXISTS (SELECT main.[login] 
        FROM dbo.EVALUATIONS_TABLE eval
        WHERE eval.[login] = @login)
    SET @startdate = DATEADD(day, 1, (SELECT END_DATE FROM (SELECT TOP 1 ID, END_DATE FROM dbo.EVALUATIONS_TABLE WHERE [LOGIN] = @login) lastscorecard));
    SET @enddate = DATEADD(day, 10, @startdate);
ELSE
    SET @startdate_new = DATEADD(day, -1, GETDATE());
    SET @enddate_new = DATEADD(day, -10, @startdate_new);

我试图在输出表变量中插入一组或另一组变量,但我仍然必须依赖相同的IFEXISTS逻辑,正如我们上面看到的那样,这是不可靠的。SQL Server如此困惑的原因是什么?我愿意重新思考我的整个逻辑,以避免出现这样的混乱:-)

您需要使用BEGIN/END,因为否则只会运行IF之后的第一个语句:

 IF EXISTS (SELECT main.[login] 
        FROM dbo.EVALUATIONS_TABLE eval
        WHERE eval.[login] = @login) BEGIN
    SET @startdate = DATEADD(day, 1, (SELECT END_DATE FROM (SELECT TOP 1 ID, END_DATE FROM dbo.EVALUATIONS_TABLE WHERE [LOGIN] = @login) lastscorecard));
    SET @enddate = DATEADD(day, 10, @startdate);
END ELSE BEGIN
    SET @startdate_new = DATEADD(day, -1, GETDATE());
    SET @enddate_new = DATEADD(day, -10, @startdate_new);
END 

"显而易见"的解决方案是对if块使用begin/end。事实上,我建议始终begin/endif一起使用,以防止出现这种类型的错误。

但是,你可以完全摆脱if

SELECT @startdate = COALESCE(DATEADD(day, 1, MAX(END_DATE)),
                             DATEADD(day, -1 GETDATE)
                            )
FROM (SELECT TOP 1 et.*
      FROM dbo.EVALUATIONS_TABLE et.
      WHERE [LOGIN] = @login
     ) l;
SELECT @enddate = DATEADD(day, -10, @startdate);

Iulia Mihet,对于这种类型的查询,应该始终使用BEGIN和END。特别是当您使用有条件的IF EXISTS查询时。你的代码应该是这样的:

IF EXISTS (SELECT main.[login] 
    FROM dbo.EVALUATIONS_TABLE eval
    WHERE eval.[login] = @login)
BEGIN
SET @startdate = DATEADD(day, 1, (SELECT END_DATE FROM (SELECT TOP 1 ID, END_DATE FROM dbo.EVALUATIONS_TABLE WHERE [LOGIN] = @login) lastscorecard));
SET @enddate = DATEADD(day, 10, @startdate);
END
ELSE
BEGIN
SET @startdate_new = DATEADD(day, -1, GETDATE());
SET @enddate_new = DATEADD(day, -10, @startdate_new);
END

希望它能帮助

您可以使用相同的变量。您已经使用了BEGIN和END。使用以下查询。

IF EXISTS (SELECT main.[login] 
    FROM dbo.EVALUATIONS_TABLE eval
    WHERE eval.[login] = @login)
BEGIN
    SET @startdate = DATEADD(day, 1, (SELECT END_DATE FROM (SELECT TOP 1 ID, END_DATE FROM dbo.EVALUATIONS_TABLE WHERE [LOGIN] = @login) lastscorecard));
    SET @enddate = DATEADD(day, 10, @startdate);
END
ELSE
BEGIN
    SET @startdate = DATEADD(day, -1, GETDATE());
    SET @enddate = DATEADD(day, -10, @startdate_new);
END

最新更新