Oracle Pipelined Table

本文介绍如何使用Oracle的管道化表函数返回多行数据,提高数据处理效率。管道化表函数能够逐步返回数据集合,适用于将数据从一种类型转换为另一种类型的应用场景。
为了让 PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成。REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合在可以返回前,必须进行具体化。Oracle 9i 通过引入的管道化表函数纠正了后一种情况。表函数是返回整个行的集(通常作为一个集合)的函数,可以直接从 SQL 语句中进行查询,就好像它是一个真正的数据库表一样。管道化表函数与之相似,但是它像在构建时一样返回数据,而不是一次全部返回。管道化表函数更加有效,因为数据可以尽可能快地返回。

管道化表函数必须返回一个集合。在函数中,PIPE ROW 语句被用来返回该集合的单个元素,该函数必须以一个空的 RETURN 语句结束,以表明它已经完成。一旦我们创建了上述函数,我们就可以使用 TABLE 操作符从 SQL 查询中调用它。

管道化表函数经常被用来把数据从一种类型转化成另一种类型。

下面是用 Pipelined Table 实现 split 函数的例子:



CREATE OR REPLACE TYPE ty_str_split IS TABLE OF VARCHAR2 (4000);

CREATE OR REPLACE FUNCTION fn_split (p_str IN VARCHAR2, p_delimiter IN VARCHAR2)
RETURN ty_str_split PIPELINED
IS
j INT := 0;
i INT := 1;
len INT := 0;
len1 INT := 0;
str VARCHAR2 (4000);
BEGIN
len := LENGTH (p_str);
len1 := LENGTH (p_delimiter);

WHILE j < len
LOOP
j := INSTR (p_str, p_delimiter, i);

IF j = 0
THEN
j := len;
str := SUBSTR (p_str, i);
PIPE ROW (str);

IF i >= len
THEN
EXIT;
END IF;
ELSE
str := SUBSTR (p_str, i, j - i);
i := j + len1;
PIPE ROW (str);
END IF;
END LOOP;

RETURN;
END fn_split;
/



测试:
SELECT * FROM TABLE (fn_split ('1;;12;;123;;1234;;12345', ';;'));

结果:
1
12
123
1234
12345

 

一个简单的例子:CREATE TYPE mytype AS OBJECT (
field1 NUMBER,
field2 VARCHAR2 (50)
);

CREATE TYPE mytypelist AS TABLE OF mytype;

CREATE OR REPLACE FUNCTION pipelineme
RETURN mytypelist PIPELINEDIS
v_mytype mytype;
BEGIN
FOR v_count IN 1 .. 20
LOOP
v_mytype := mytype (v_count, 'Row ' || v_count);
PIPE ROW (v_mytype); END LOOP;

RETURN;
END pipelineme;

SELECT * FROM TABLE (pipelineme);
FIELD1 FIELD2
------ ------------------------
1 Row 1
2 Row 2
3 Row 3
4 Row 4
5 Row 5
6 Row 6
7 Row 7
8 Row 8
9 Row 9
10 Row 10
11 Row 11
12 Row 12
13 Row 13
14 Row 14
15 Row 15
16 Row 16
17 Row 17
18 Row 18
19 Row 19
20 Row 20

20 rows selected

 
### Oracle 数据库面试题及答案汇总 #### 1. **什么是 PL/SQL?它的主要特点有哪些?** PL/SQL 是一种过程化的编程语言,专为 Oracle 数据库设计。它允许开发者编写复杂的程序逻辑来操作数据库对象和数据。其特点是支持高并发访问,同时保持数据的一致性和完整性[^1]。 以下是 PL/SQL 的一些重要特性: - 支持变量声明、条件判断以及循环结构。 - 可以嵌套 SQL 查询语句,实现动态的数据处理。 - 提供异常处理机制,便于捕获和管理运行时错误。 ```sql DECLARE v_employee_name VARCHAR2(50); BEGIN SELECT first_name INTO v_employee_name FROM employees WHERE employee_id = 1; DBMS_OUTPUT.PUT_LINE('Employee Name: ' || v_employee_name); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('No data found.'); END; ``` --- #### 2. **如何利用视图和物化视图优化查询性能?** 视图是一种虚拟表,基于基础表的查询结果构建而成。而物化视图则会物理存储这些查询的结果,适用于需要频繁执行相同复杂查询的情况。通过预计算并缓存数据,物化视图能显著降低实时查询的压力[^2]。 配置物化视图时可以选择不同的刷新策略(如定时或手动),以满足不同业务场景的需求。此外,Oracle 优化器会在适当情况下自动选择物化视图作为查询源,进一步提升性能。 --- #### 3. **TABLE Function 的作用是什么?** TABLE Function 是一种特殊的函数类型,可以通过 PL/SQL 返回一组记录集,并将其当作普通表或视图使用。这类功能通常应用于管道 (Pipeline) 处理或者 ETL 流程中,帮助高效传输大量数据[^3]。 下面是一个简单的 TABLE Function 示例: ```plsql CREATE OR REPLACE TYPE number_table_type AS TABLE OF NUMBER; CREATE OR REPLACE FUNCTION generate_numbers(p_count IN NUMBER) RETURN number_table_type PIPELINED IS BEGIN FOR i IN 1..p_count LOOP PIPE ROW(i); END LOOP; RETURN; END; SELECT * FROM TABLE(generate_numbers(5)); ``` 上述代码创建了一个名为 `generate_numbers` 的表格函数,它可以生成指定数量的连续整数序列。 --- #### 4. **分析以下 SQL 语句为何报错:** ```sql SELECT dept.*, COUNT(emp.*) FROM emp, dept WHERE emp.deptno = dept.deptno GROUP BY deptno; ``` 此语句存在语法问题,因为当使用 GROUP BY 子句时,所有非聚合列都必须显式包含在分组字段列表中。这里只指定了 `deptno` 而未提及其他来自 `dept.*` 的列名,因此违反了规则[^4]。 修正后的版本如下所示: ```sql SELECT dept.deptno, dept.dname, COUNT(emp.empno) FROM emp JOIN dept ON emp.deptno = dept.deptno GROUP BY dept.deptno, dept.dname; ``` --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值