【问题标题】:If Exists command in setting a variableIf Exists 命令用于设置变量
【发布时间】:2018-02-25 00:18:36
【问题描述】:

我有一个有效的 IF EXISTS 命令来选择表中已经存在的 PID_GUID,或者如果表中不存在该值来选择用作 PID_GUID 的值。命令如下所示;

IF EXISTS (SELECT PID_GUID FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595')
 BEGIN
   SELECT PID_GUID FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595'
 End
 ELSE
   SELECT 'a70600f4-1cff-4284-a2ce-5eb19f47cf19'

现在我想做的就是把它放入设置一个这样的变量;

Daclare @OLDPID = VARCHAR(36)
SET @OLDPID = IF EXISTS (SELECT PID_GUID FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595')
 BEGIN
   SELECT PID_GUID FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595'
 End
 ELSE
   SELECT 'a70600f4-1cff-4284-a2ce-5eb19f47cf19'

我将如何在 SQL2008 中执行此操作?

【问题讨论】:

    标签: sql sql-server variables if-statement exists


    【解决方案1】:

    在每个语句中设置变量:

    IF EXISTS (SELECT PID_GUID FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595')
     BEGIN
       SELECT @OLDPID = PID_GUID
       FROM PID
       WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595'
     End
     ELSE
       SELECT @OLDPID = 'a70600f4-1cff-4284-a2ce-5eb19f47cf19';
    

    其实我会更倾向于使用:

    DECLARE @OLDPID VARCHAR(36) = 'a70600f4-1cff-4284-a2ce-5eb19f47cf19';
    IF EXISTS (SELECT PID_GUID
               FROM PID
               WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595'
              )
     BEGIN
         SELECT @OLDPID = PID_GUID
         FROM PID
         WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595';
     END;
    

    【讨论】:

    • 您实际上可以完全消除 EXISTS。只需将变量设置为默认值,然后您的 select 语句即可使用查询填充它。如果没有返回任何行,则该值仍将是默认值。 :)
    • @Shawn 我出于习惯使用select 1exists()not exists() 都不返回行,因此您可以使用 select nullselect 1。基于这篇文章EXISTS Subqueries: SELECT 1 vs. SELECT * - Conor Cunningham 使用select 1 将避免在查询编译期间检查该表的任何不需要的元数据。 EXISTS Subqueries: SELECT 1 vs. SELECT * - Martin Smith 运行的测试显示实际性能没有差异。
    • @SeanLange 我看到你没有阅读我评论的后半部分。 - 马丁史密斯的回答在第二个链接中涵盖了所有这些。此外,查询的编译不同于查询的执行。
    • @SqlZim 是的,我在阅读第二篇文章之前发表了我的评论,该文章驳斥了第一篇文章的作者所说的话。 :)
    • @SqlZim 对不起,“返回行”对我来说有点过于简单化了。我的意思是IF EXISTS 只是检查是否存在记录。我刚刚尝试了SELECT 1/0:非常有趣。谢谢,肖恩。那就是“确认你不知道你不知道的事情”的事情之一。我会说,在阅读了 Zim 的两个链接后,我倾向于相信那些在编译器上工作的人,但仅限于他们工作的版本。第 2 篇文章表明,它在 2011/14 年的运作方式与 2008 年的预期不同。
    【解决方案2】:

    我会使用COALESCE(),因为COALESCE() 可以做任何事情。

    SELECT @OLDPID = COALESCE((SELECT PID_GUID 
                              FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595'
                              FETCH FIRST 1 ROW ONLY),
                              'a70600f4-1cff-4284-a2ce-5eb19f47cf19')
    

    我们不需要臭气熏天的 IF 语句!

    SQL 服务器 --

    SELECT @OLDPID = COALESCE((SELECT TOP 1 PID_GUID 
                              FROM PID WHERE EDI_ID = '12874' OR PID = 'ROBERT' OR PID = 'R595'),
                              'a70600f4-1cff-4284-a2ce-5eb19f47cf19')
    

    【讨论】:

    • 我喜欢这个。这将处理 PID 中已经存在的 NULL PID_GUID。那么问题是这是否是预期的行为。如果在PID 中已经是NULL,Gordon 的查询将生成@OLDPID = NULL。但是,如果 NULL 是有效响应,则会覆盖它。但是,是的,COALESCE() 非常棒。 :-)
    • @user3463443 对于 SQL 2008,只需使用 SELECT TOP 1 PID_GUID 并删除 FETCH FIRST 1 ROW ONLY。我认为那是 DB2。 MS SQL 有一个 FETCH,但它需要与 OFFSET(游标外部)一起使用,并且仅在 2012+ 中有效。
    • @user3463443 -- 是的,如果您使用的是 SQL Server,那么按照 Shawn 的建议使用 TOP 1 语法
    猜你喜欢
    • 1970-01-01
    • 2011-12-24
    • 2022-01-23
    • 1970-01-01
    • 2018-11-18
    • 2012-07-22
    • 2022-01-24
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多