在案例陈述中退出查询?


8

我正在尝试设置一个查询,以便它将比较来自两个不同表的两个日期,如果它们相等,则查询退出。如果它们不相等,则查询将继续并插入一些内容。我不知道如何使它做我想要的。

SELECT TOP(1) @dateA=a.someDate
FROM a
ORDER BY DESC;
SELECT TOP(1) @dateB=b.someDate
FROM b
ORDER BY DESC;

CASE WHEN @dateA=@dateB THEN raiseerror('dates equal',20,-1) with log;

Insert statements;

任何帮助将不胜感激。


SQL的其他一些变体同时具有一个表达式和一个名为的语句CASE-SQL Server仅具有该CASE表达式。
RDFozz

3
您实际上是否要提出该错误?还是只是尝试退出?
凯文(Kevin)

Answers:


16

CASE 是一个表达式(不是语句),不能像这样用于流程控制-不要调用命令,不要返回多个列/值,也不能单独用作命令。

在我看来,您可以仅IF在日期相等时使用该错误,否则请运行插入。

IF @dateA = @dateB 
BEGIN
  raiseerror('dates equal',20,-1) with log;
END
ELSE -- maybe you don't need a batch-aborting, logging error level
BEGIN
  INSERT ...
END

您也可以采用其他方式。仅当日期不相等时才运行插入,否则引发错误:

IF @dateA <> @dateB
BEGIN
  INSERT ...
END
ELSE
BEGIN
  raiserror ...
END

如果你认为使用错误为获得运行插件出来的目的,那么你可以只从去除一切ELSE下来,因为刀片将运行的唯一途径是,当@dateA@dateB不相等的

IF @dateA <> @dateB
BEGIN
  INSERT ...
END

我已经缩减了对行(相对于“记录”)和列(相对于“字段”)之类的书呆子的态度,但是正是由于这个原因,整个表达式与语句之间的区别是非常重要的。请参阅“ CASE表达式的肮脏秘密 ”。


除一个nitpick以外,通常是一个很好的答案。使用'<>'运算符不能很好地与NULL值一起使用。如果您的日期值之一为NULL,则“不等于”运算符将返回意外结果。尝试以下“在(1 <> NULL)THEN'!='ELSE'=='END的情况下进行选择”
user5151179

1
@ user5151179我很确定亚伦知道区别。还要检查问题中的OP是否说明了两个日期相等时他想做什么,以及两个日期不相等时他想做什么。当他们中的一个或两个都在一起时,他根本没有提到他们想干什么NULL。仍然很好的观察到,在这种情况下,Aaron提供的两个版本会做不同的事情。
ypercubeᵀᴹ

6

使用IF而不是CASE

 IF @dateA=@dateB 
    raiseerror('dates equal',20,-1) with log;
 ELSE
    BEGIN
        Insert statements;
    END

当然,这假设您确实要引发错误。另一个选择是:

 IF @dateA<>@dateB 
    BEGIN
        Insert statements;
    END

现在,注意BEGINEND。这些将很重要。该IF语句(和ELSE)仅影响其下方的命令。如果需要多个命令,则需要BEGIN和END


2

其他答案指出,CASE是一个表达式,而不是一个语句,因此本身不能包含语句(例如RAISEERROR或其他语句)。如前所述,如果条件不是很多,尤其是当条件只是一种时,IF语句是您要执行的操作的理想选择。

但是,根据您的情况,仍然可以使用CASE表达式,只是不完全符合您的显示方式。特别是,如果要检查匹配条件导致一组相同动作的条件很多(例如引发异常和终止脚本),则可以在存储CASE结果的赋值语句中使用CASE表达式,然后执行使用IF检查存储的结果并在适当的情况下执行所需的操作,例如:

DECLARE @ErrorMessage varchar(1000);

SET @ErrorMessage =
  CASE WHEN @dateA = @dateB THEN
    'Dates equal'
  CASE WHEN ... /* some other condition */ THEN
    'Some other message'
  .
  .
  .
  ELSE
    ''  -- no message if nothing is wrong;
        -- you can also omit the ELSE branch entirely,
        -- which means the same as ELSE NULL
  END
;

IF @ErrorMessage <> ''
BEGIN
  RAISERROR (@ErrorMessage, 20, -1) WITH LOG;
END;

... /* continue the script */

在这种情况下,所需的操作引发了异常,但是与异常一起返回的消息需要取决于首先检查的条件。赋值语句使用CASE表达式选择要存储在@ErrorMessage变量中的消息。

您还可以看到仅在变量实际包含要显示的消息的情况下,才有条件引发错误。如果该值为空字符串或null,则脚本将继续运行而不会中断。


0

您需要变量吗?

declare @D1 table (dt date);
declare @D2 table (dt date);
insert into @D1 values ('2000-01-01'), ('2000-02-01');
insert into @D2 values ('2000-01-01'), ('2000-02-01');
if (select max(dt) from @D1) = (select max(dt) from @D2)
begin 
   select 'match'
end
else 
begin 
   select 'no match'
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.