《Oracle PL/SQL开发指南》学习笔记31——源码调试——函数和过程(第三部分,并行查询及管道函数)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hpdlzu80100/article/details/84799853

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 optimizer may run undesignated functions  when it believes they are safe for parallel operations. Java methods and external C programs are  never deemed safe for parallel operations.  The following function supports parallel SQL operations and merges last name, first name,  and middle initial into a single string:

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 行。

猜你喜欢

转载自blog.csdn.net/hpdlzu80100/article/details/84799853