《Oracle PL/SQL開發指南》學習筆記31——原始碼除錯——函式和過程(第三部分,並行查詢及管道函式)
1. PARALLEL_ENABLE子句(啟用並行查詢以提高效能)
首次接觸,學習一下:
PARALLEL_ENABLE lets you designate a function to support parallel query capabilities. This type of guarantee requires that a function doesn’t read or write data from external sources, like packages or database tables. You should consider designating functions as safe for parallel operations to improve throughput, but the Oracle Database 12c
SQL> CREATE OR REPLACE FUNCTION merge 2 ( last_name VARCHAR2 3 , first_name VARCHAR2 4 , middle_initial VARCHAR2 ) 5 RETURN VARCHAR2 PARALLEL_ENABLE IS 6 BEGIN 7 RETURN last_name ||', '||first_name||' '||middle_initial; 8 END; 9 / 函式已建立。 FULL_NAME ------------------------------ Jane, Moss Wendy Jane, Royal Elizabeth Jonah, Gretelz Simon Nathan, Smith Brian Potter, Albus Severus Potter, Ginny Potter, Harry Potter, James Sirius Potter, Lily Luna Sweeney, Ian M Sweeney, Matthew Sweeney, Meaghan Vizquel, Doreen Vizquel, Oscar Ward, Brandt Henry Ward, Clinton Goeffrey Winn, Brian Winn, Randi 已選擇 18 行。
2. PIPELINED子句
首次接觸,學習一下:
The PIPELINED clause provides improved performance when functions return collections, like varray or table collections. You’ll also note performance improvements when returning system reference cursors by using the PIPELINED clause. Pipelined functions also let you return aggregate tables. Aggregate tables act like collections of PL/SQL record structures. They only work in SQL statements. This section discusses collection concepts. Chapter 6 covers collections for those new to PL/SQL. Collections are arrays and lists of scalar and compound variables. Pipelined functions only work with table or varray collections. These two types of collections are indexed by sequential numbers. You can also build collections of user-defined SQL object types, which are treated like single-dimensional arrays of number, strings, or dates.
SQL> ? desc
DESCRIBE
--------
Lists the column definitions for a table, view, or synonym,
or the specifications for a function or procedure.
DESC[RIBE] {[schema.]object[@connect_identifier]}
SQL> CREATE OR REPLACE
2 TYPE numbers AS VARRAY(10) OF NUMBER
3 /
型別已建立。
SQL> DESC numbers
numbers VARRAY(10) OF NUMBER
SQL> CREATE OR REPLACE FUNCTION pipelined_numbers
2 RETURN NUMBERS
3 PIPELINED IS
4 list NUMBERS := numbers(0,1,2,3,4,5,6,7,8,9);
5 BEGIN
6 FOR i IN 1..list.LAST LOOP
7 PIPE ROW(list(i));
8 END LOOP;
9 RETURN;
10 END;
11 /
函式已建立。
SQL> SELECT *
2 FROM TABLE (pipelined_numbers);
COLUMN_VALUE
------------
0
1
2
3
4
5
6
7
8
9
已選擇 10 行。
3. 管道函式示例
首次接觸管道函式,學習一下:
“
1、管道函式即是可以返回行集合(可以使巢狀表nested table 或陣列 varray)的函式,我們可以像查詢物理表一樣查詢它或者將其 賦值給集合變數。
2、管道函式為並行執行,在普通的函式中使用dbms_output輸出的資訊,需要在伺服器執行完整個函式後一次性的返回給客戶端。如果需要在客戶端 實時的輸出函式執行過程中的一些資訊,在oracle9i以後可以使用管道函式(pipeline function)。
3、關鍵字PIPELINED表明這是一個oracle管道函式,oracle管道函式的返回值型別必須為集合,在函式中,PIPE ROW語句被用來返回該集合的單個元素,函式以一個空的RETURN 語句結束,以表明它已經完成。
4、由於管道函式的併發多管道流式設計以及實時返回查詢結果而去除了中間環節因此可以帶來可觀的效能提升。”
SQL> CREATE OR REPLACE PACKAGE pipelined IS
2 /* Declare a PL/SQL record and collection type. */
3 TYPE account_record IS RECORD
4 ( account VARCHAR2(10)
5 , full_name VARCHAR2(42));
6 TYPE account_table IS TABLE OF account_record;
7
8 /* Declare a pipelined function. */
9 FUNCTION pf RETURN account_table PIPELINED;
10 END pipelined;
11 /
程式包已建立。
SQL> ed
已寫入 file afiedt.buf
1 CREATE OR REPLACE PACKAGE BODY pipelined IS
2 -- Implement a pipelined function.
3 FUNCTION pf
4 RETURN account_table
5 PIPELINED IS
6 /* Declare a collection control and collection variable. */
7 counter NUMBER := 1;
8 account ACCOUNT_TABLE := account_table();
9 /* Define a cursor. */
10 CURSOR c IS
11 SELECT m.account_number
12 , c.last_name || ', '||c.first_name full_name
13 FROM member m JOIN contact c ON m.member_id = c.member_id
14 ORDER BY c.last_name, c.first_name, c.middle_name;
15 BEGIN
16 FOR i IN c LOOP
17 /* Allot space and add values to collection. */
18 account.EXTEND;
19 account(counter).account := i.account_number;
20 account(counter).full_name := i.full_name;
21 /* Assign the collection element to the PIPE. */
22 PIPE ROW(account(counter));
23 counter := counter + 1;
24 END LOOP;
25 RETURN;
26 END pf;
27* END pipelined;
SQL> /
程式包體已建立。
SQL> SELECT *
2 FROM TABLE(pipelined.pf);
ACCOUNT FULL_NAME
---------- ------------------------------
SLC-000020 Jane, Moss
SLC-000022 Jane, Royal
SLC-000021 Jonah, Gretelz
SLC-000023 Nathan, Smith
SLC-000024 Potter, Albus
SLC-000024 Potter, Ginny
SLC-000024 Potter, Harry
SLC-000024 Potter, James
SLC-000024 Potter, Lily
SJC-000003 Sweeney, Ian
SJC-000003 Sweeney, Matthew
SJC-000003 Sweeney, Meaghan
SJC-000002 Vizquel, Doreen
SJC-000002 Vizquel, Oscar
SLC-000019 Ward, Brandt
SLC-000018 Ward, Clinton
SJC-000001 Winn, Brian
SJC-000001 Winn, Randi
4. 模式級(獨立)管道函式
SQL> ed
已寫入 file afiedt.buf
1 CREATE OR REPLACE FUNCTION pf
2 RETURN pipelined.account_table
3 PIPELINED IS
4 -- Declare a collection control variable and collection variable.
5 counter NUMBER := 1;
6 account PIPELINED.ACCOUNT_TABLE := pipelined.account_table();
7 -- Define a cursor.
8 CURSOR c IS
9 SELECT m.account_number
10 , c.last_name || ', '||c.first_name full_name
11 FROM member m JOIN contact c ON m.member_id = c.member_id
12 ORDER BY c.last_name, c.first_name, c.middle_name;
13 BEGIN
14 FOR i IN c LOOP
15 account.EXTEND;
16 account(counter).account := i.account_number;
17 account(counter).full_name := i.full_name;
18 PIPE ROW(account(counter));
19 counter := counter + 1;
20 END LOOP;
21 RETURN;
22* END pf;
SQL> /
函式已建立。
SQL> SELECT * FROM TABLE(pf);
ACCOUNT FULL_NAME
---------- ------------------------------
SLC-000020 Jane, Moss
SLC-000022 Jane, Royal
SLC-000021 Jonah, Gretelz
SLC-000023 Nathan, Smith
SLC-000024 Potter, Albus
SLC-000024 Potter, Ginny
SLC-000024 Potter, Harry
SLC-000024 Potter, James
SLC-000024 Potter, Lily
SJC-000003 Sweeney, Ian
SJC-000003 Sweeney, Matthew
SJC-000003 Sweeney, Meaghan
SJC-000002 Vizquel, Doreen
SJC-000002 Vizquel, Oscar
SLC-000019 Ward, Brandt
SLC-000018 Ward, Clinton
SJC-000001 Winn, Brian
SJC-000001 Winn, Randi
已選擇 18 行。