代码之家  ›  专栏  ›  技术社区  ›  BFF

在case语句问题中使用when exists

  •  0
  • BFF  · 技术社区  · 8 年前

    如果“高级”选项卡中存在来自tabC的成员和成员级别,我希望将“颜色”设置为“金色”。现在,如果我在“高级”选项卡中只有一个记录,它就可以工作了。但是,当我在premium\u选项卡中有多个记录时,它会将它们的所有“color”值设置为null(“”),而不管该成员是否存在于tabC中。不确定问题是什么,如何解决?

    begin for rec in premium_tab
     loop for rec1 in default_tab
      loop insert into attire_tab (outfit, outfit_val)
       values (rec1.outfit_code,
               case rec1.outfit_code when 'color' then (case when exists (select 'x' from tabC where member=rec.user and member_levl=rec.lvl)
                                                             then 'gold' else '' end)
                                     else 'other' end);
         end loop; end loop; end;
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Caius Jard    8 年前

    INSERT attire_tab(outfit,outfit_val)
    SELECT  
      rec1.outfit_code, 
      case 
        when rec1.outfit_code = 'color' 
          case when tabc.member is not null then 'gold' else '' end
        else 'other'
      end
    FROM
      premium_tab rec 
      CROSS JOIN
      default_tab rec1
      LEFT JOIN
      tabC
      ON
        tabc.member=rec.user and tabc.member_levl=rec.levl
    

    这种方法没有什么好处:

    您正在编写一个select查询(在开发过程中注释插入行),它基本上体现了您要插入的整个数据块—在查询工具中很容易完成,它是只读的,可以多次运行和测试,无需执行“编写存储过程代码,运行存储过程,从表中选择要检查,将表擦除回开始状态,修改存储过程,再次运行存储过程“

    第二,db query engine可以随意优化查询,而不必在存储过程代码的逐行属性强制执行的步骤集中运行查询。避免逐行操作而使用数据块几乎总是更好的。如果rec和rec1各有1000行,那么现有的查询可能会运行一百万次。如果tabc只有100行,那么对现有数据进行连接以查找与成员相关的一小部分行肯定比对表或其索引进行一百万次(一千次查找的一千次重复)要快

    以及预防说明;如果rec和tabc之间的关系是m:m,那么左连接将导致行的相乘,称为笛卡尔积。处理这种情况需要额外的注意,因为exists路由只询问rec是否有任何一个匹配的tabc行,但是这个路由将它们连接起来。我最初认为特定的高级行只与一个成员相关,因此可以安全地使用左连接