PL/SQL Challenge 每日一题:2016-4-13 BULK COLLECT批量获取

[复制链接]
查看11 | 回复3 | 2008-9-15 01:28:12 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。
每两周的优胜者可获得itpub奖励的技术图书一本。
以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808
原始出处:
http://www.plsqlchallenge.com/
作者:Steven Feuerstein
运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品
我执行了这些语句:
CREATE TABLE plch_employees
(
employee_id INTEGER PRIMARY KEY,
last_name VARCHAR2 (100)
)
/
BEGIN
FOR indx IN 1 .. 100
LOOP
INSERT INTO plch_employees
VALUES (indx, 'Name' || indx);
END LOOP;
COMMIT;
END;
/
哪些选项在执行之后会显示 "Total Count = 100" ?
(A)
DECLARE
TYPE employee_ntt IS TABLE OF plch_employees%ROWTYPE;
l_plch_employees employee_ntt;
BEGIN
EXECUTE IMMEDIATE 'SELECT * FROM plch_employees'
BULK COLLECT INTO l_plch_employees;
DBMS_OUTPUT.put_line (
'Total Count = ' || l_plch_employees.COUNT);
END;
/
(B)
DECLARE
my_cursor
SYS_REFCURSOR;
TYPE employee_ntt IS TABLE OF plch_employees%ROWTYPE;
l_plch_employees employee_ntt;
BEGIN
OPEN my_cursor FOR 'SELECT * FROM plch_employees';
FETCH my_cursor BULK COLLECT INTO l_plch_employees;
DBMS_OUTPUT.put_line ('Total Count = ' || l_plch_employees.COUNT);
CLOSE my_cursor;
END;
/
(C)
DECLARE
c_limit CONSTANT INTEGER := 50;
my_cursor
SYS_REFCURSOR;
TYPE employee_ntt IS TABLE OF plch_employees%ROWTYPE;
l_plch_employees employee_ntt;
l_total PLS_INTEGER := 0;
BEGIN
OPEN my_cursor FOR 'SELECT * FROM plch_employees';
LOOP
FETCH my_cursor BULK COLLECT INTO l_plch_employees LIMIT c_limit;
EXIT WHEN l_plch_employees.COUNT = 0;
l_total := l_total + l_plch_employees.COUNT;
END LOOP;
DBMS_OUTPUT.put_line ('Total Count = ' || l_total);
CLOSE my_cursor;
END;
/
(D)
DECLARE
c_query CONSTANT VARCHAR2 (1000) :=
'SELECT * FROM plch_employees';
l_total PLS_INTEGER := 0;
BEGIN
FOR rec IN c_query
LOOP
l_total := l_total + 1;
END LOOP;
DBMS_OUTPUT.put_line ('Total Count = ' || l_total);
END;
/

回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
选ABC
C中的bulk collect 使用了limit,会分成两次处理,每次处理50条记录,数量之和为100,D会报错,c_query不是游标
回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
答案ABC, 2楼得奖。
A: (不推荐)
这个方法动态执行SELECT语句,并且在一个上下文切换获取了所有的数据行。这是很快的,但如果表很大,集合会消耗许多(太多)内存,可能会导致会话内存错误。这方法的另一个问题是它今天可能运行得好好的,但是随着时间推移表行数会增长,出错的几率也会增加。
B: (不推荐)
这个方法动态执行SELECT语句,并且在一个上下文切换获取了所有的数据行,这回用的是一个游标变量。这是很快的,但如果表很大,集合会消耗许多(太多)内存,可能会导致会话内存错误。这方法的另一个问题是它今天可能运行得好好的,但是随着时间推移表行数会增长,出错的几率也会增加。
C:(推荐)
现在我用了OPEN FOR来把动态构建的SELECT语句用游标变量打开。然后我打开一个循环,每次之获取有限数量的行。相比起无限制的BULK COLLECT, 这个选项的总体性能可能会有所下降,但是我不用担心内存错误。并且很可能性能差别是无法察觉的。如果有差别,可以试着增加你的限制数量。
D: 这个选项无法执行。你不能把动态SELECT用于FOR循环。

回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
谢谢版主
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行