管道函数(pipelined function)简单使用示例

-----------------------------Cryking原创------------------------------
-----------------------转载请注明出处,谢谢!------------------------ 

 

管道函数是一种比较特殊的函数,其返回值为集合类型.

在PL/SQL中,管道函数和表函数、游标一起联合使用能实现一些比较复杂的功能,当和并行处理一起使用时,还能较大的改善性能.

使用示例1:

实现简单的字符串分割,函数参数为常见的VARCHAR2类型.

--先创建集合类型,供管道函数返回使用

23:38:14 SCOTT@orcl> CREATE OR REPLACE TYPE EMP_element as table of varchar2(100);
23:54:04   2  /

Type created.

Elapsed: 00:00:00.11


 建立管道函数

create or replace function pipe_test(p_empno varchar2,
                                     p       varchar2 default ',')
  return EMP_element
  pipelined is
  v_element varchar2(1000) := p_empno;
begin
  pipe row(substr(p_empno, 0, instr(p_empno, p) - 1));
  loop
    v_element := substr(v_element,
                        instr(v_element, p) + 1,
                        length(v_element) - instr(v_element, p) + 1);
    exit when instr(v_element, p) = 0;
    pipe row(substr(v_element, 0, instr(v_element, p) - 1));
  end loop;
  pipe row(v_element);
  return;
end pipe_test;


注意pipelined及pipe row等关键字.

pipelined表明该函数为管道函数,pipe row用来立即返回单个元素.

使用如下:

01:06:16 SCOTT@orcl>  select pipe_test(empno||','||ename) a from emp;

A
------------------------------
EMP_ELEMENT('7369', 'SMITH')
EMP_ELEMENT('7499', 'ALLEN')
EMP_ELEMENT('7521', 'WARD')
EMP_ELEMENT('7566', 'JONES')
EMP_ELEMENT('7654', 'MARTIN')
EMP_ELEMENT('7698', 'BLAKE')
EMP_ELEMENT('7782', 'CLARK')
EMP_ELEMENT('7788', 'SCOTT')
EMP_ELEMENT('7839', 'KING')
EMP_ELEMENT('7844', 'TURNER')
EMP_ELEMENT('7876', 'ADAMS')
EMP_ELEMENT('7900', 'JAMES')
EMP_ELEMENT('7902', 'FORD')
EMP_ELEMENT('7934', 'MILLER')

14 rows selected.

Elapsed: 00:00:00.04


即每一行为一个集合变量.

 也可以通过表函数查询单个集合元素的值:(这里可看作一种单行转单列的应用)

01:07:28 SCOTT@orcl>  select * from table( select pipe_test(empno||','||ename) A
 from emp where empno=7788);

COLUMN_VALUE
--------------------------------------------------
7788
SCOTT

2 rows selected.

Elapsed: 00:00:00.01


 

使用示例2:

使用集合类型做函数传入参数类型.

建立函数如下:

create or replace function pipe_test1(c_empno EMP_element,
                                      p       varchar2 default ',')
  return EMP_element
  pipelined is
  v_element varchar2(1000);
begin
  for i in 1 .. c_empno.count loop
    v_element := c_empno(i);
    pipe row(substr(v_element, 0, instr(v_element, p) - 1));
    loop
      v_element := substr(v_element,
                          instr(v_element, p) + 1,
                          length(v_element) - instr(v_element, p) + 1);
      exit when instr(v_element, p) = 0;
      pipe row(substr(v_element, 0, instr(v_element, p) - 1));
    end loop;
    pipe row(v_element);
  end loop;
  return;
end pipe_test1;


注意嵌套表类型的使用.

使用与上面的基本类似:

01:13:16 SCOTT@orcl> col a format a50
01:13:22 SCOTT@orcl> select pipe_test1(EMP_element(ename||','||'ename',empno||',
'||'empno')) a from emp;

A
--------------------------------------------------
EMP_ELEMENT('SMITH', 'ename', '7369', 'empno')
EMP_ELEMENT('ALLEN', 'ename', '7499', 'empno')
EMP_ELEMENT('WARD', 'ename', '7521', 'empno')
EMP_ELEMENT('JONES', 'ename', '7566', 'empno')
EMP_ELEMENT('MARTIN', 'ename', '7654', 'empno')
EMP_ELEMENT('BLAKE', 'ename', '7698', 'empno')
EMP_ELEMENT('CLARK', 'ename', '7782', 'empno')
EMP_ELEMENT('SCOTT', 'ename', '7788', 'empno')
EMP_ELEMENT('KING', 'ename', '7839', 'empno')
EMP_ELEMENT('TURNER', 'ename', '7844', 'empno')
EMP_ELEMENT('ADAMS', 'ename', '7876', 'empno')
EMP_ELEMENT('JAMES', 'ename', '7900', 'empno')
EMP_ELEMENT('FORD', 'ename', '7902', 'empno')
EMP_ELEMENT('MILLER', 'ename', '7934', 'empno')

14 rows selected.

Elapsed: 00:00:00.01


 

01:14:02 SCOTT@orcl> select * from table(select pipe_test1(EMP_element(ename||',
'||'ename',empno||','||'empno')) from emp where empno=7788);

COLUMN_VALUE
--------------------------------------------------
SCOTT
ename
7788
empno

4 rows selected.

Elapsed: 00:00:00.02


 还可以用游标做管道函数的传入参数类型,这里就不演示了,留给大家自己去练习!

 

管道函数使用注意项:

1.返回类型必须是集合类型,否则会报错:PLS-00630

2.在声明部分(定义部分)不能使用管道函数(也不能定义管道函数),否则会报错:PLS-00653

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个使用管道函数的 Oracle 存储过程示例代码: ``` CREATE OR REPLACE TYPE dept_type AS OBJECT ( deptno NUMBER, dname VARCHAR2(14), loc VARCHAR2(13) ); CREATE OR REPLACE TYPE dept_tab_type AS TABLE OF dept_type; CREATE OR REPLACE FUNCTION get_dept_info (p_deptno IN NUMBER) RETURN dept_tab_type PIPELINED AS l_dept dept_type; BEGIN FOR r IN (SELECT deptno, dname, loc FROM dept WHERE deptno = p_deptno) LOOP l_dept := dept_type(r.deptno, r.dname, r.loc); PIPE ROW(l_dept); END LOOP; RETURN; END; CREATE OR REPLACE PROCEDURE display_dept_info (p_deptno IN NUMBER) AS BEGIN FOR r IN (SELECT * FROM TABLE(get_dept_info(p_deptno))) LOOP DBMS_OUTPUT.PUT_LINE('Deptno: ' || r.deptno || ', Dname: ' || r.dname || ', Loc: ' || r.loc); END LOOP; END; ``` 这个存储过程定义了一个 `dept_type` 类型和一个 `dept_tab_type` 表类型,然后定义了一个名为 `get_dept_info` 的函数,该函数接受一个部门编号参数,并返回一个 `dept_tab_type` 表类型,其中包含指定部门的信息。函数使用 `PIPELINED` 关键字表示它是一个管道函数,可以逐行返回结果。 最后,存储过程 `display_dept_info` 调用 `get_dept_info` 函数并打印返回的部门信息。 ### 回答2: Oracle 存储过程管道函数示例代码如下: ```sql -- 创建一个简单的存储过程管道函数,返回指定范围内的奇数 CREATE OR REPLACE FUNCTION get_odd_numbers( start_number IN NUMBER, end_number IN NUMBER) RETURN SYS_REFCURSOR PIPELINED AS v_number NUMBER := start_number; BEGIN WHILE v_number <= end_number LOOP IF MOD(v_number, 2) = 1 THEN PIPE ROW(v_number); -- 将当前奇数放入管道中 END IF; v_number := v_number + 1; END LOOP; RETURN; END; / ``` 此示例代码创建了一个名为get_odd_numbers的存储过程管道函数,接受两个参数start_number和end_number,用于指定返回的奇数范围。函数内部通过一个循环判断每个数是否为奇数,并将奇数依次放入管道中。最后通过RETURN语句返回结果。 使用该存储过程管道函数可以通过以下方式获取奇数: ```sql -- 调用存储过程管道函数 SELECT * FROM TABLE(get_odd_numbers(1, 10)); ``` 上述代码将返回1至10之间的所有奇数:1、3、5、7、9。 ### 回答3: Oracle存储过程管道函数是一种特殊类型的存储过程,它可以返回一个结果集。下面是一个示例代码,用于说明Oracle存储过程管道函数的用法: ```sql -- 创建一个管道对象作为存储过程的返回类型 CREATE OR REPLACE TYPE employee_info AS OBJECT ( employee_id NUMBER, full_name VARCHAR2(100), hire_date DATE ); / -- 创建一个管道表类型,用于存储多个employee_info对象 CREATE OR REPLACE TYPE employee_table AS TABLE OF employee_info; / -- 创建一个具有管道函数功能的存储过程 CREATE OR REPLACE FUNCTION get_employees RETURN employee_table PIPELINED AS BEGIN -- 在这里可以编写查询语句,获取想要的员工数据 -- 这里仅做示例,假设从一个名为employees的表中获取数据 FOR emp IN (SELECT employee_id, first_name || ' ' || last_name AS full_name, hire_date FROM employees) LOOP -- 将查询结果逐行插入管道表中 PIPE ROW(employee_info(emp.employee_id, emp.full_name, emp.hire_date)); END LOOP; RETURN; END; / -- 调用存储过程管道函数,并输出结果 SELECT * FROM TABLE(get_employees()); ``` 上述代码中,首先我们创建了一个管道对象`employee_info`,它包含了三个属性:`employee_id`、`full_name`和`hire_date`。然后,我们创建了一个管道表类型`employee_table`,用于存储多个`employee_info`对象。 接着,我们创建了一个具有管道函数功能的存储过程`get_employees`,其中使用了一个游标`emp`来存储查询结果。通过`PIPE ROW`语句,我们将每一行查询结果插入到管道表中。最后,通过`RETURN`语句返回结果。 最后,在主程序中我们通过`SELECT`语句调用存储过程管道函数,并使用`TABLE`函数将结果显示出来。 这个示例代码演示了如何使用Oracle存储过程管道函数来获取员工信息,并将查询结果作为一个结果集返回。通过这种方式,我们可以更加灵活地处理和使用存储过程的输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值