2017-03-16 97 views
1

一个表格包含序列号和时间戳以及其他数据。 存储过程需要2个参数,并且用户可以传入空序列号。两个参数之一的WHERE子句

这就是我想实现,但它不工作(SQL说附近有语法错误>)

create proc dbo.MyProc(@SequenceNo int, @Timestamp datetime) as 
begin 
    select * from MyTable where 
     case when @SequenceNo is not null THEN SequenceNo > @SequenceNo 
       ELSE Timestamp > @Timestamp 
     end 
end 

如何做到这一点?

+0

我有,但我认为这将是标准的SQL – CashCow

+0

到位分配值'THEN'部分,为什么你要检查表达式是否大于?,你可以在这里指定一个真正的假,1或0或你选择的任何其他值 – Saurabh

+0

它应该表示当&SequenceNo不为null时使用此作为条件的基础,否则使用时间戳。 SequenceNo>&SequenceNo应返回true或false的条件。如果为false,我希望跳过这一行,我不想尝试更多的情况。 (用你知道的代替& – CashCow

回答

2

您可以使用下面的代码。它使用where子句中的情况下声明:

declare proc.MyProc(@SequenceNo int, @Timestamp datetime) as 
begin 
    select * 
    from MyTable 
    where 
     1 = case 
       when @SequenceNo is not null and SequenceNo > @SequenceNo then 1 
       when @SequenceNo is null and Timestamp > @Timestamp then 1 
       else 0 
      end 
end 
+0

就像我一直在寻找但不起作用。看起来像第二个时候还需要检查@SequenceNo为空。 – CashCow

+0

我明白了,所以它只在@SequenceNo为空时检查时间戳。我已更新查询。 –

+0

是的,这是有效的。我并不是100%满意,仍然是因为我真的希望“非空”成为第一个案例,然后根据第二个条件返回真或假的内容。 – CashCow

1

你的代码看起来像SQL Server(尽管这对答案没有什么不同)。在一般情况下,最好是离开CASE表现出来的WHERE条款和只使用布尔逻辑:

select t.* 
from MyTable t 
where (@SequenceNo is not null and SequenceNo > @SequenceNo) or 
     (@SequenceNo is null and Timestamp > @Timestamp); 

因为NULL值失败的所有比较,可以简化这:

select t.* 
from MyTable t 
where (SequenceNo > @SequenceNo) or 
     (@SequenceNo is null and Timestamp > @Timestamp); 

而且,如果你想在值来传递,并有过滤功能,也许这是有用的:

select t.* 
from MyTable t 
where (SequenceNo > @SequenceNo or @SequenceNo is null) and 
     (Timestamp > @Timestamp or @Timestamp is null); 

它不是一样的逻辑,但很可能是你想要的。在下面的格式

+0

最后一个可能有用,但当然不会像所有情况下的其他两个一样返回。 – CashCow

+0

这可能足够我所需要的。在真正的查询中,选择中有更多逻辑,即少数连接,所以我不需要2个过程。 – CashCow

0

使用CASE语句:

DECLARE proc dbo.MyProc(@SequenceNo int, @Timestamp datetime) as 
BEGIN 
    SELECT * FROM MyTable 
    WHERE SequenceNo = CASE WHEN (@SequenceNo IS NOT NULL OR SequenceNo > 
     @SequenceNo) THEN @SequenceNo ELSE SequenceNo END 
     AND Timestamp = CASE WHEN @SequenceNo IS NULL AND Timestamp > 
     @Timestamp THEN @Timestamp ELSE Timestamp END 
END 
0

使用动态查询像这样

CREATE PROCEDURE MyProc 
 
( 
 
    @SequenceNo int, @Timestamp datetime 
 
) 
 
AS 
 
BEGIN 
 
DECLARE @SQL Nvarchar(max) 
 
SELECT \t @SQL = N'select * from MyTable where' 
 

 
IF @SequenceNo IS NOT NULL 
 
BEGIN 
 
    SELECT @SQL = @SQL + N' SequenceNo > @SequenceNo'; 
 
END 
 
ELSE 
 
    BEGIN 
 
    SELECT @SQL = @SQL + N' Timestamp > @Timestamp'; 
 
    END 
 

 
EXEC(@SQL) 
 
END