存储过程与条件结果

时间:2010-07-02 18:24:55

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

我想编写一个类似这样的存储过程:

SELECT * from T where T.A = @a and T.B = @b

如果返回行,则返回这些行,否则返回

SELECT * from T where T.A = @a and T.B IS NULL

修改

感觉应该有一种方法来创建一个程序,使其运行第一个查询一次,并仅在必要时运行第二个查询

结束编辑。

我能管理的最好的是跟随,它(理论上)运行第一个查询两次,除非它可能被缓存:

IF EXISTS (SELECT * from T where T.A = @a and T.B = @b) THEN
    SELECT * from T where T.A = @a and T.B = @b
ELSE
    SELECT * from T where T.A = @a and T.B IS NULL

值得一提的是,这是在Microsoft SQL Server 2008中

7 个答案:

答案 0 :(得分:5)

这应该避免存在检查的附加表访问。我不确定是否有更简洁的方式。

SELECT * from T where T.A = @a and T.B = @b


IF (@@ROWCOUNT = 0)
BEGIN
    SELECT * from T where T.A = @a and T.B IS NULL
END

答案 1 :(得分:1)

我认为您可以使用表变量执行此操作,这应该避免两个结果集问题。类似的东西:

declare @result1 table ( ... )
insert into @result1 select * from T where T.A = @a and T.B = @b

if (@@rowcount = 0)
   select * from T where T.A = @a and T.B is null
else
   select * from @result1

答案 2 :(得分:0)

您也可以在一个查询中执行此操作:

SELECT * from T where (T.A = @a and T.B = @b) OR
( 0=(SELECT COUNT(*) T1 where (T1.A = @a and T1.B = @b) ) 
  AND T.A = @a and T.b IS NULL)

答案 3 :(得分:0)

为什么不能在一个查询中执行此操作:

Select ...
From T
Where T.A = @a
    And T.B = @b
Union All
Select ...
From T
Where T.A = @a
    And T.B Is Null
    And Not Exists  (
                    Select 1
                    From T
                    Where T.A = @a
                        And T.B = @b
                    )

另一个单一查询解决方案:

Select ...
From T
Where T.A = @a
    And T.B = @b
Union All
(Select ...
From T
Where T.A = @a
    And T.B Is Null
Except
Select ...
From T
Where T.A = @a
    And T.B = @b)

答案 4 :(得分:0)

我不知道它是否在性能上有所帮助,但你可以尝试表值函数:

create function fun(@a <aType>, @b <bType>)
 returns @result (<...columns...>)
as begin
 insert into @result
 select * from T where T.A = @a and T.B = @b;

 if  (@@ROWCOUNT = 0) begin
  insert into @result
  select * from T where T.A = @a and T.B is null;
 end;
 return;
end;
GO

但我怀疑它有帮助。

一般来说,我会坚持你的原创方法。这是最简单,最干净的。缓存和良好的索引应该关注性能。

如果这里存在真正的性能问题,我会退一步看看这个数据库设计。你为什么在那里有空?你为什么要尝试两个过滤器?可以用不同的方式建模吗?如果没有,可能会有一点反规范化?

答案 5 :(得分:0)

尝试此操作,如果第一个选择返回行,则如果第一个选择失败,则返回行,然后下一个选择返回,或者最后一个选择返回:

IF EXISTS(SELECT * FROM Customers 

     INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID where Customers.CustomerID='BERJGS')
    BEGIN
             SELECT * FROM Customers 
                    INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID where Customers.CustomerID='BERJGS'
              PRINT 'TOLA'
              RETURN
     END
ELSE
     BEGIN
               SELECT * FROM Customers 
                    INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID where Customers.CustomerID='6CHOPS'             
              IF @@ROWCOUNT > 0             
                    RETURN              
              --RETURN
     END



SELECT * FROM Customers  where Customers.CustomerID='FRANK'

答案 6 :(得分:-2)

编辑在编辑问题后编辑了答案。

CREATE PROCEDURE myconditionalsp
@a  <type>,
@b  <type>
AS

SELECT * from T 
where 
    -- the second condition is true AND the first condition is false
    (((T.A = @a) and (T.B IS NULL)) AND NOT ((T.A = @a) and (T.B = @b)))
    OR 
    -- the first condition is true (regardless what is the second condition)
    ((T.A = @a) and (T.B = @b))
GO