暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 使用管道功能或过程导出枢轴数据

askTom 2017-08-16
240

问题描述

我需要创建一个函数 (或存储过程?),它需要pivoted数据并输出它。外部流程
需要调用函数/过程并接收数据。数据行数总是变化的; 没有设置限制。然而,存在大量的数据 (例如75,000)。

我从多个表联接中获得大量数据。然后我对这些数据进行透视,这样它就会有
108列和多行 (大量行)。我需要创建一个函数 (或存储过程??)
这将输出枢轴数据行。我有两个问题:
1) 在不使用管道功能的情况下获取要编译的功能
2) 如何将管道功能实现到代码中。(我在这方面找到了各种例子,但是
到目前为止,没有一个有用的。)

以下是代码的简要概述:


create or replace
FUNCTION NOMT_EXPORT_FUNC
(
  PARAM_START_DATE IN DATE  
, PARAM_END_DATE IN DATE 
) RETURN NomT_DataTbl PIPELINED IS 

  nom_start_date DATE := PARAM_START_DATE;
  nom_end_date DATE := PARAM_END_DATE;

CREATE OR REPLACE TYPE NomT_RowsExport AS OBJECT
(
  deal_num number(32,0),
  tran_num number(32,0),
  ba_tenant varchar2(32),
  from_ba varchar2(32),
  to_ba varchar2(32),
  from_ca varchar2(32),
  to_ca varchar2(32),
  sched_start_date DATE,

-- ****  Columns where v00 is column for 0000, v01 is column for 0015, ... v99 is column for 2545
-- *****  All columns and columns 2500, 2515, 2530, 2545 can be renamed


  v00 number(32,6) DEFAULT 0.0,
  v01 number(32,6) DEFAULT 0.0,
  v02 number(32,6) DEFAULT 0.0,
  v03 number(32,6) DEFAULT 0.0,
  v04 number(32,6) DEFAULT 0.0,
  v05 number(32,6) DEFAULT 0.0,
  v06 number(32,6) DEFAULT 0.0,
  v07 number(32,6) DEFAULT 0.0,
  v08 number(32,6) DEFAULT 0.0,
  v09 number(32,6) DEFAULT 0.0,
 :
 :
 :
  v91 number(32,6) DEFAULT 0.0,
  v92 number(32,6) DEFAULT 0.0,
  v93 number(32,6) DEFAULT 0.0,
  v94 number(32,6) DEFAULT 0.0,
  v95 number(32,6) DEFAULT 0.0,
  v96 number(32,6) DEFAULT 0.0,
  v97 number(32,6) DEFAULT 0.0,
  v98 number(32,6) DEFAULT 0.0,
  v99 number(32,6) DEFAULT 0.0
)

CREATE OR REPLACE TYPE NomT_DataTbl 
  AS TABLE OF NomT_RowsExport;
  
BEGIN


WITH qtr_hr_vols AS 
(
  SELECT "all the data needed for the pivot"; 
 
)
 
select * from qtr_hr_vols
 PIVOT (
 SUM (sched_volume) FOR sched_hour IN ('0000', '0015', '0030', '0045', '0100', '0115', '0130', '0145', '0200', 
 '0215', '0230', '0245', '0300', '0315', '0330', '0345', '0400', 
 '0415', '0430', '0445', '0500', '0515', '0530', '0545', '0600', 
 '0615', '0630', '0645', '0700', '0715', '0730', '0745', '0800', 
 '0815', '0830', '0845', '0900', '0915', '0930', '0945', '1000', 
 '1015', '1030', '1045', '1100', '1115', '1130', '1145', '1200', 
 '1215', '1230', '1245', '1300', '1315', '1330', '1345', '1400', 
 '1415', '1430', '1445', '1500', '1515', '1530', '1545', '1600', 
 '1615', '1630', '1645', '1700', '1715', '1730', '1745', '1800', 
 '1815', '1830', '1845', '1900', '1915', '1930', '1945', '2000', 
 '2015', '2030', '2045', '2100', '2115', '2130', '2145', '2200', 
 '2215', '2230', '2245', '2300', '2315', '2330', '2345', '2500', 
 '2515', '2530', '2545')
)
ORDER BY deal_num, schedule_date;

-- ?????????????????
--  Create a loop here to pipeline the data from the pivot table  ?????
--  The amount of data rows is always varied.

  RETURN NULL;
END NOMT_EXPORT_FUNC;

专家解答

1.我不明白你的意思。为什么你要写一个没有管道的流水线函数

2.是的,您需要创建一个从查询中获取数据的循环。然后在每次迭代中将结果管道到输出对象中。

您可以在以下位置找到几个示例:

http://www.oracle-developer.net/display.php?id=429
https://stevenfeuersteinonplsql.blogspot.co.uk/2015/04/table-functions-introduction-and.html(第1部分,共6个系列)
https://oracle-base.com/articles/misc/pipelined-table-functions

当然,这里的另一个问题是你为什么使用流水线函数?

要访问此数据,外部进程仍需要执行查询,例如:

select * from table(your_pipelined_fn)


那么,为什么不让它首先运行pivot查询呢?

或者你可以调查:

-返回ref光标,并让外部应用程序根据需要获取结果
-只是返回一个对象数组 (而不是一个流水线函数)。由于您有很多数据,您可能希望在此过程中包含某种形式的分页 (获取前100行,然后是下100等)。不过,您需要弄清楚如何使调用之间的结果保持一致...

如果您需要更详细的帮助,请发布一个完整的测试用例,其中包括

-表DDL (创建表)
-样本数据 (插入)
-您期望从您的过程中获得的输出
-您尝试过的解释不起作用 (ORA错误,为什么输出错误的描述,...)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论