仅在查询结果非空时返回选择查询的结果

3

使用Sql Server。编写存储过程。以下是我想要实现的伪代码:

    IF EXISTS ( SELECT  field1
                FROM    t1
                WHERE   field1 = ... AND field2 = ...) 
        BEGIN
            SELECT  field1
                FROM    t1
                WHERE   field1 = ... AND field2 = ...
        END

有没有更好的方法来完成这个任务?非常感谢您的帮助。

Chirayu

更新:问题在于同一个查询被执行了两次。我也不能只运行一次查询并返回null(如果结果为null,我想返回另一个结果)。


2
据我所知,这种方法有什么问题吗? - marc_s
1
它运行了相同的查询两次。 - Chirayu Shishodiya
然后只需运行第二个查询 - 如果不存在任何内容,则将返回NULL - marc_s
2
@marc_s 其实在这种情况下将返回一个空结果集。也许是个小问题,但你将无法检查结果列是否为IS NULL,因为那里没有勺子。 - Aaron Bertrand
@Chirayu:如果EXISTS条件返回false,您想退出过程还是在else情况下执行另一个查询?您能详细说明目标是什么吗?从你的例子中可以看出,如果EXISTS条件返回false,你只想退出过程。 - James Johnson
关于您的更新:如果“替代结果”结构不同(列数及其名称,数据类型等),那么@Remus Rusanu的答案仍然适用,即“从任何API使用都将是一场噩梦”。如果结构相同,则应该能够编写一个查询,例如UNION两个结果。但是,没有看到其他结果的查询很难进行概括。 - onedaywhen
4个回答

4

我之前用过CTE和表变量来完成这个任务,虽然需要更多代码行数,但查询只需编写一次,因此你的逻辑只存在一个地方。

DECLARE @Results TABLE (Result INT);
WITH ResultsCTE AS
(
    --Your query goes here 
    SELECT  1 as Result 
    WHERE 1 = 1
)
INSERT INTO @Results
SELECT Result
FROM ResultsCTE

IF (SELECT COUNT(*) FROM @Results) > 0
BEGIN
    SELECT * FROM @Results
END
ELSE BEGIN
    SELECT 'Do Something Else or Do Nothing!'
END

3

当然 - 你可以将第一次查询执行的值捕获到一个变量中,然后检查 @@rowcount > 0。如果为真,则返回该变量,否则执行你的 else 条件。 - Chris B. Behrens
不,你使用 DECLARE @field1 <data type>; SELECT @field1 = field1 FROM t1 ...<where>...; IF @@ROWCOUNT > 0 SELECT @field1; ... 然而似乎你的应用程序需要检查结果是否存在,提供一个空的结果集似乎比根本不提供结果集更合适。该应用程序如何检查是否有结果集呢? - Aaron Bertrand
@Aaron - 如果我猜的话,我认为他将会检查多个条件,并且只想返回一个结果集,无论哪个有结果。 - JNK
@JNK 希望原帖作者能够明确实际需求,而不是让我们猜测他们的最终需求。 :-) - Aaron Bertrand
@aaron - 不过猜测起来更有趣! - JNK
显示剩余2条评论

2
如果选择没有产生任何结果,则不会返回任何结果。我看不出在这里使用条件的原因,除非我漏掉了什么...

返回一个空结果集,这与没有结果集是不同的。我不能代表OP说话,但依赖于这种差异的应用程序并不是不合理的。 - Michael J Swart
在结果从过程中返回的情况下,额外的条件意味着必须执行两个查询而不是一个,这最终会降低性能。即使没有结果,仍然会执行查询,因此也没有任何收益。通过只进行选择并让它返回空结果集,无论是否返回结果,过程只需执行一个查询。 - James Johnson
(这是Swart)肯定没有性能提升,但逻辑上是不同的。从标题、问题和问题更新中可以清楚地看出,OP不想返回一个空结果集。 - Michael J Swart

2
有时返回结果,有时不返回结果的存储过程将会成为任何API的噩梦。客户端API具有不同的入口点,具体取决于是否返回结果集 (SqlCommand.ExecuteReader) 。如果不返回结果集,则使用另一个入口点 (SqlCommand.ExecuteNonQuery)。应用程序无法提前知道应该使用哪个API!建模工具使用 SET FMTONLY 选项来分析返回结果集的元数据,当返回的结果集随机变化时,建模工具就会非常困惑。换句话说,您走错了路,请停下来掉头。
只需运行查询,如果没有行符合条件,它将简单地返回一个空的结果集。这正是每个客户端API和建模工具从您的过程中期望的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接