我想编写一个类似这样的存储过程:
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中
答案 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