【问题标题】:Inner Query In Oracle Stored ProcedureOracle 存储过程中的内部查询
【发布时间】:2015-08-25 14:19:28
【问题描述】:

尝试编写存储过程。我在存储过程中有一个游标,它产生以下输出。

 ID1 | Range | Action | Version | Name
--------------------------------------
  1  | 1-3,  |        |         |
     | 5-7   |   D    |   V0    |  U1
  2  | 10-11 |   A    |   V0    |  U2
  3  | 15-18 |   A    |   V1    |  U3

其中 range 是另一个表 UPCListDetailsID

 ID | UPCName
--------------
 1  | Test
 2  | Test1
 3  | Test2
 10 | Test10
...

现在我需要使用范围列查询UPCListDetails 表并生成输出

 ID1 | ID | UPCName | Action | Version | Name
----------------------------------------------
 1   | 1  | Test    | D      | V0      | U1
 1   | 2  | Test1   | D      | V0      | U1
 1   | 3  | Test2   | D      | V0      | U1
 2   | 10 | Test10  | A      | V1      | U2

基本上,我需要使用范围查询 UPCListDetails 表(范围列中的低值和高值)并将其存储在某个变量中,然后再次将值注入结果中。我正在阅读有关 PLSQL 集合的信息,但我无法理解它。

【问题讨论】:

  • 欢迎使用 StackOverflow:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ({ } ) 在编辑器工具栏上很好地格式化和语法突出显示它!
  • id1 = 1 的游标输出是两行,还是范围列“1-3, 5-7”中的数据?
  • 感谢 Boneist 的回复。它是单行。范围列值为 "1-3, 5-7" 。也可以不带“-”,如“10-11”(如上例第二行所示)

标签: sql oracle stored-procedures


【解决方案1】:

最好使用 2 列和每个范围一行来维护范围:

ID1  Range_From  Range_To  Action Version Name
1    1           3         D      V0      U1
2    5           7         D      V0      U1
3    10          11        A      V0      U2
4    15          18        A      V1      U3

那么你只需要一个类似的查询

select u.ID, u.UPCName, r.Action r.Version r.Name
from   UPCListDetails u
       join range_table r
       on u.ID between r.range_from and r.range_to;

这样您就不必解析范围和范围列表。

【讨论】:

    【解决方案2】:

    如果您能够更改程序中的光标,以便它以@TonyAndrews 的解决方案建议的格式输出数据,那么我建议您这样做。

    但是,如果您不知道该光标输出,那么您需要将其转换为该格式:

    with      output as (select 1 id1, '1-3, 5-7' range, 'D' action, 'V0' version, 'U1' name from dual union all
                         select 2 id1, '10-11' range, 'A' action, 'V0' version, 'U2' name from dual union all
                         select 3 id1, '15-18' range, 'A' action, 'V1' version, 'U3' name from dual),
             main_op as (select id1,
                                regexp_substr(regexp_substr(replace(range, ' '), '[^,]+', 1, level), '[^-]+', 1, 1) range_from,
                                regexp_substr(regexp_substr(replace(range, ' '), '[^,]+', 1, level), '[^-]+', 1, 2) range_to,
                                action,
                                version,
                                name
                         from   output
                         connect by prior id1 = id1
                                    and level <= regexp_count(range, ',') + 1
                                    and prior dbms_random.value is not null),
      upclistdetails as (select 1 id, 'Test' upcname from dual union all
                         select 2 id, 'Test1' upcname from dual union all
                         select 3 id, 'Test2' upcname from dual union all
                         select 10 id, 'Test10' upcname from dual)
    select mo.id1,
           uld.id,
           uld.upcname,
           mo.action,
           mo.version,
           mo.name
    from   upclistdetails uld
           inner join main_op mo on uld.id between mo.range_from and mo.range_to;
    
           ID1         ID UPCNAME ACTION VERSION NAME
    ---------- ---------- ------- ------ ------- ----
             1          1 Test    D      V0      U1  
             1          2 Test1   D      V0      U1  
             1          3 Test2   D      V0      U1  
             2         10 Test10  A      V0      U2 
    

    main_op 子查询首先为每个 id1 生成与范围块一样多的行(例如,对于 id1 = 1,有 2 个范围块),在其自己的行上输出每个块。

    然后我们将连字符之前的元素用作“range_from”列,同样我们将连字符之后的元素用作“range_to”。

    一旦您的输出看起来像这样,只需将其加入 upclistdetails 表即可获得最终结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-05
      • 2013-10-12
      • 2018-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      相关资源
      最近更新 更多