Oracle Select查询动态参数条件

时间:2014-11-01 05:56:04

标签: sql oracle plsql

帮我写一下选择查询

我有3张表如下

Subscriber
############################

Subscr_id   parent id
---------   ---------
1            100
2            100
3            101
4            101

因此在一个父ID下可以有多个subscr_id(这些被称为位置)。其他表是

Products
############################

Subscr_id   products   businessline
---------   --------   -------------
1            5100       100
1            1100       200
2            3100       300

Addons
############################

Subscr_id   products   businessline  addons
---------   ---------  ------------  ------
1            5100       100            1
1            5100       100            5
1            5100       100            30
1            1100       200            5
1            1100       200            25

现在我有四个参数-1)产品2)业务线3)插件4)用户将给出的父ID。但1,2,3都不是强制性的。

对于输入的父ID,我将根据以下条件输出true,否则为false

  1. 如果只提供产品,那么如果父母的某个地点的产品具有产品=给定的产品输入,则结果为真
  2. 如果只提供业务,那么如果父母的某个位置具有businessline =给定业务线的条目,则结果为真
  3. 如果同时提供了业务和产品,那么如果父项的某个位置具有businessline =给定业务线且产品=给定产品
  4. 的条目,则结果将为真
  5. 如果只给出了插件,那么如果父节点的某个位置在Addons表中有addons =给定插件的条目,则结果为true 像这样可以有很多条件
  6. 我想写一个选择查询

4 个答案:

答案 0 :(得分:0)

我根据您的数据在我的本地数据库中尝试过。程序如下 在下面的过程中,我使用了一些符号

  • Subscr_id as sid
  • 父ID为pid
  • businessline as bl
  • 产品为专业

    declare 
    given_pro number(5):=&given_pro;
    given_bl number(5):=&given_bl;
    given_addons number(5):=&given_addons;
    as 
    cursor cur is 
    select distinct S.PID from subscriber s,product p,addons a where 
    (nvl(given_pro,1)=given_pro and nvl(given_bl,1)=1 and S.SID=P.SID and A.PRO=given_pro and p.pro=given_pro and A.PRO=P.PRO and A.SID=S.SID and P.SID=A.SID)
    or
    (nvl(given_bl,1)=given_bl and nvl(given_pro,1)=1 and A.BL=given_bl and p.bl=given_bl and S.SID=P.SID and A.BL=P.BL and A.SID=S.SID and P.SID=A.SID)
    or
    (nvl(given_bl,1)=given_bl and nvl(given_pro,1)=given_pro and A.PRO=given_pro and p.pro=given_pro and A.BL=given_bl and p.bl=given_bl and S.SID=P.SID and A.PRO=P.PRO and A.BL=P.BL and A.SID=S.SID and P.SID=A.SID)
    or
    (nvl(given_addons,1)=given_addons and nvl(given_bl,1)=1 and nvl(given_pro,1)=1 and A.SID=S.SID);
    rec cur%rowtype;
    begin
    open cur;
    loop 
    fetch cur into rec;
    exit when cur%notfound;
    dbms_output.put_line(rec.pid ||'  hello');
    end loop;
    close cur;
    end;
    

这个程序只给你pid

答案 1 :(得分:0)

您没有提供有关实施的大量细节,所以:

  1. 假设您可以让订户包含没有插件的产品和产品我已经为这些表使用了外连接
  2. 我使用了一个子查询来传递参数值,因为这是在the inevitable SQL Fiddle中测试组合的最简单方法。
  3. 所以这是一个解决方案,它实现了您在问题中指定的四个条件,以及(products + businessline + addons)的奖励。

    with cte as (select sub.*
                        , prod.products
                        , prod.businessline
                        , adds.addons
                 from subscriber sub
                      left outer join products prod
                            on prod.Subscr_id = sub.Subscr_id
                      left outer join addons adds
                            on adds.Subscr_id = prod.Subscr_id
                               and adds.products = prod.products
                               and adds.businessline = prod.businessline
               )
        , params as ( select 100 as par_id
                             , 1100 as prod_id
                             , 200 as bus_id
                             , null as add_id
                       from dual )
    select cte.* 
    from cte
         cross join params
    where cte.parent_id = params.par_id
    and ( 
      (params.prod_id = cte.products and params.bus_id is null and params.add_id is null)
      or (params.prod_id is null and params.bus_id = cte.businessline and params.add_id is null)
      or (params.prod_id = cte.products and params.bus_id = cte.businessline and params.add_id is null)
      or (params.prod_id is null and params.bus_id is null and params.add_id = cte.addons)
      or (params.prod_id = cte.products and params.bus_id = cte.businessline and params.add_id = cte.addons)
      )
    order by cte.subscr_id, cte.products, cte.businessline, cte.addons
    /
    

    如果这不是您想要的,请编辑您的问题并澄清您的情况。

答案 2 :(得分:0)

我根据要求修改了查询

用cte as(select sub。*                     ,prod.prod_code                     ,prod.bus_line_code                     ,adds.add_on_code              来自订户子                   left outer join subscriber_bl_product prod                         on prod.Subscr_id = sub.Subsr_id                   left outer join subscriber_bl_product_add_on添加                         在adds.Subscr_id = prod.Subscr_id                            和adds.prod_code = prod.prod_code                            和adds.bus_line_code = prod.bus_line_code            )     ,params as(选择100作为par_id                          ,null为prod_id                          ,null为bus_id                          ,100为add_id                    来自双重)

选择不同的cte.parent_id 来自cte      交叉加入参数 其中cte.parent_id = params.par_id 和(   (params.prod_id = cte.prod_code和params.bus_id为null且params.add_id为null)   或(params.prod_id为null,params.bus_id = cte.bus_line_code和params.add_id为null)   或(params.prod_id = cte.prod_code和params.bus_id = cte.bus_line_code和params.add_id为空)   或(params.prod_id为null,params.bus_id为null,params.add_id = cte.add_on_code)   或(params.prod_id = cte.prod_Code和params.bus_id = cte.bus_line_code和params.add_id = cte.add_on_code)   ) ;

答案 3 :(得分:0)

我能够使用动态sql

来做到这一点

谢谢你的回答。这真的对我很有帮助:))

declare
v_prod number(8) := 22  ;
v_bus number(8) := 01 ;
v_add number(8) := 6666666;
v_add_stat varchar2(1):= 'T';
v_sql varchar2(32767);
begin
v_sql := 'select * from
subscriber where subsr_id = :parent and exists (select * from '|| (case when v_add  is not null or v_add_stat is not null  then ' subscriber_bl_product_add_on ' else 'subscriber_bl_product' end )
||' where subscr_id in (select subsr_id from subscriber where parent_id = :parent ) '
||case when v_prod is not null then 'and prod_code = '||v_prod  else '' end|| case when v_bus is not null then  ' and bus_line_code = '||v_bus  else  ''  end ||case when v_add is not null then ' and add_on_code = '||v_add  else '' end ||case when v_add_stat is not null then ' and add_on_Stat_ind = ''' ||v_add_stat||'''' else '' end ||')';
dbms_output.put_line(v_sql);
execute immediate v_sql;
end;