【问题标题】:How to include single row multiple column subquery (PIPELINED function) results in the result set如何在结果集中包含单行多列子查询(PIPELINED 函数)结果
【发布时间】:2017-11-15 08:19:39
【问题描述】:

我正在使用 Oracle 11g。

所以,假设我有一个像这样的测试数据表

with test_data as (
    select 1 as id, 'John' as name from dual 
        union all
    select 2 as id, 'Jack' as name from dual
        union all
    select 3 as id, 'Peter' as name from dual
)

我还有一个piplined 函数,每次调用返回一行多列如下:

CREATE OR REPLACE PACKAGE MY_PACK AS
  TYPE result_record is RECORD(
   surname           varchar2(27),
   telephone          varchar2(50),
   place_of_birth     varchar2(50)
       );

  TYPE result_table IS TABLE OF result_record;
  function runPipe(id number) RETURN result_table PIPELINED;
END ERC_PACK;
/

CREATE OR REPLACE PACKAGE BODY MY_PACK AS
    function runPipe(id number) RETURN result_table PIPELINED IS
    rec           result_record:=null;
    begin
       if  (id=1) then
         select 'Smih','139289289','Paris' into rec from dual;
       end if;
       if  (id=2) then
         select 'Lock','1888888888','London' into rec from dual;
       end if;
       if  (id=3) then
         select 'May','99999999999','Berlin' into rec from dual;
       end if;
       pipe row (rec);
       return;
  end;
END ERC_PACK;
/

当然还有

select * from table(MY_PACK.runPipe(1)) 

返回

Smih    139289289   Paris

现在我想要一个 select 语句,它将返回 test_data 的所有行以及来自管道函数的相应值

例如像

select test_data.*, (select * from table(MY_PACK.runPipe(id))) from test_data

当然不起作用预期结果会是这样的:

1 John  Smih    139289289   Paris
2 Jack  Lock    1888888888  London
3 Peter May     99999999999 Berlin

那么在给定test_data表和pipelined函数的情况下,如何实现上述预期结果?

【问题讨论】:

    标签: sql oracle plsql pipelined-function


    【解决方案1】:

    试试这个选择:

        with test_data as (
        select 1 as id, 'John' as name from dual 
            union all
        select 2 as id, 'Jack' as name from dual
            union all
        select 3 as id, 'Peter' as name from dual
    )
    select td.*, s.*
    from test_data td
    LEFT JOIN  table(MY_PACK.runPipe(td.id)) s ON 1 = 1;
    

    【讨论】:

    • 这很好用。但是你可以使用内连接而不是左连接。
    • 这确实有效——即使使用from test_data td, table(MY_PACK.runPipe(td.id)) s(不需要左连接)......太糟糕了,不能用from test_data td, (select * table(MY_PACK.runPipe(td.id))) s 做同样的事情,这对我的现实世界问题真的很有帮助——但是这不在我最初的问题中 - 所以我接受了。谢谢!!!
    【解决方案2】:

    你可以使用OUTER APPLY:

    select td.*, s.*
    from test_data td
    outer apply (select * from table(MY_PACK.runPipe(td.id))) s
    

    【讨论】:

    • 这是 12c 的吗? 11g还有什么办法吗?
    • @Plirkee Oracle 12c
    • 不幸的是我有 11g ... 有什么想法吗?
    【解决方案3】:

    请使用别名尝试以下操作

    with test_data as (
    select 1 as id, 'John' as name from dual 
        union all
    select 2 as id, 'Jack' as name from dual
        union all
    select 3 as id, 'Peter' as name from dual
    )
    select * from table(MY_PACK.runPipe(test_data.id))) from test_data
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多