使用case语句问题存在时的

时间:2018-10-14 07:37:54

标签: sql oracle plsql

如果来自tabC的member和member_levl存在于premium_tab中,我希望将'color'设置为'gold'。现在,如果我在premium_tab中只有1条记录,它确实可以工作。但是,当我在premium_tab中有多个记录时,无论成员在tabC中是否存在,它都会将其所有“颜色”值设置为null('')。不确定问题是什么以及如何解决?

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 个答案:

答案 0 :(得分:1)

作为基于集合的操作:

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

这种方法没有什么好处:

您正在编写一个选择查询(注释在开发过程中插入了INSERT行),它实质上体现了您要插入的整个数据块-在查询工具中很容易做到,它是只读的,可以运行多次测试并完善,而无需执行“编写sproc代码,运行sproc,从表中选择进行检查,将表擦除回初始状态,修改sproc,再次运行sproc”

二,db查询引擎可以自由地优化查询,但是它喜欢而不是必须按照sproc代码逐行性质强制执行的一组步骤来运行查询。最好避免使用逐行操作,而采用数据块。如果rec和rec1各自具有一千行,则该存在的查询可能可以运行一百万次。如果tabc仅具有100行,那么对现有数据进行联接以查找与成员相关的行中的一小部分肯定比击中表或其索引一百万次(一千次重复一千次)更快查找)

和注意事项;如果rec和tabc之间的关系是m:m,则左联接将导致行的相乘,称为笛卡尔积。处理这种情况需要格外小心,因为存在路由仅询问rec是否具有任何匹配的tabc行,但是此路由将它们连接起来。最初,我认为特定的高级行仅涉及一个成员,因此左联接可以安全使用