Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
16.04.2013
Размер:
5.97 Mб
Скачать

Setting Up Transformation Pipelines with Table Functions

END;

/

select plsql_code_type from user_plsql_object_settings where name = 'HELLO_NATIVE';

alter session set plsql_code_type='INTERPRETED';

The procedure is immediately available to call, and runs as a shared library directly within the Oracle process. If any errors occur during compilation, you can see them using the USER_ERRORS view or the SHOW ERRORS command in SQL*Plus.

Limitations of Native Compilation

Debugging tools for PL/SQL do not handle procedures compiled for native execution.

When many procedures and packages (typically, over 15000) are compiled for native execution, the large number of shared objects in a single directory might affect system performance. See "Setting Up PL/SQL Native Library Subdirectories" on page 11-27 for a workaround.

Real Application Clusters and PL/SQL Native Compilation

Because any node might need to compile a PL/SQL subprogram, each node in the cluster needs a C compiler and correct settings and paths in the $ORACLE_HOME/plsql/spnc_commands file.

When you use PLSQL native compilation in a Real Application Clusters (RAC) environment, the original copies of the shared library files are stored in the databases, and these files are automatically propagated to all nodes in the cluster. You do not need to do any copying of libraries for this feature to work.

The reason for using a server parameter file (SPFILE) in the examples in this section, is to make sure that all nodes of a RAC cluster use the same settings for the parameters that control PL/SQL native compilation.

Setting Up Transformation Pipelines with Table Functions

This section describes how to chain together special kinds of functions known as table functions. These functions are used in situations such as data warehousing to apply multiple transformations to data.

Major topics covered are:

Overview of Table Functions

Writing a Pipelined Table Function

Overview of Table Functions

Table functions are functions that produce a collection of rows (either a nested table or a varray) that can be queried like a physical database table or assigned to a PL/SQL collection variable. You can use a table function like the name of a database table, in the FROM clause of a query, or like a column name in the SELECT list of a query.

A table function can take a collection of rows as input. An input collection parameter can be either a collection type (such as a VARRAY or a PL/SQL table) or a REF CURSOR.

Execution of a table function can be parallelized, and returned rows can be streamed directly to the next process without intermediate staging. Rows from a collection returned by a table function can also be pipelined—that is, iteratively returned as they

11-28 PL/SQL User's Guide and Reference

Setting Up Transformation Pipelines with Table Functions

are produced instead of in a batch after all processing of the table function's input is completed.

Streaming, pipelining, and parallel execution of table functions can improve performance:

By enabling multi-threaded, concurrent execution of table functions

By eliminating intermediate staging between processes

By improving query response time: With non-pipelined table functions, the entire collection returned by a table function must be constructed and returned to the server before the query can return a single result row. Pipelining enables rows to be returned iteratively, as they are produced. This also reduces the memory that a table function requires, as the object cache does not need to materialize the entire collection.

By iteratively providing result rows from the collection returned by a table function as the rows are produced instead of waiting until the entire collection is staged in tables or memory and then returning the entire collection.

Example 11–9 Example: Querying a Table Function

The following example shows a table function GetBooks that takes a CLOB as input and returns an instance of the collection type BookSet_t. The CLOB column stores a catalog listing of books in some format (either proprietary or following a standard such as XML). The table function returns all the catalogs and their corresponding book listings.

The collection type BookSet_t is defined as:

CREATE TYPE Book_t AS OBJECT ( name VARCHAR2(100), author VARCHAR2(30), abstract VARCHAR2(1000));

/

CREATE TYPE BookSet_t AS TABLE OF Book_t;

/

-- The CLOBs are stored in a table Catalogs:

CREATE TABLE Catalogs ( name VARCHAR2(30), cat CLOB );

Function GetBooks is defined as follows:

CREATE FUNCTION GetBooks(a CLOB) RETURN BookSet_t;

/

The query below returns all the catalogs and their corresponding book listings.

SELECT c.name, Book.name, Book.author, Book.abstract

FROM Catalogs c, TABLE(GetBooks(c.cat)) Book;

Example 11–10 Example: Assigning the Result of a Table Function

The following example shows how you can assign the result of a table function to a PL/SQL collection variable. Because the table function is called from the SELECT list of the query, you do not need the TABLE keyword.

CREATE TYPE numset_t AS TABLE OF NUMBER;

/

CREATE FUNCTION f1(x number) RETURN numset_t PIPELINED IS

BEGIN

FOR i IN 1..x LOOP

PIPE ROW(i);

Tuning PL/SQL Applications for Performance 11-29

Setting Up Transformation Pipelines with Table Functions

END LOOP;

RETURN;

END;

/

-- pipelined function in from clause select * from table(f1(3));

Using Pipelined Table Functions for Transformations

A pipelined table function can accept any argument that regular functions accept. A table function that accepts a REF CURSOR as an argument can serve as a transformation function. That is, it can use the REF CURSOR to fetch the input rows, perform some transformation on them, and then pipeline the results out.

For example, the following code sketches the declarations that define a StockPivot function. This function converts a row of the type (Ticker, OpenPrice, ClosePrice) into two rows of the form (Ticker, PriceType, Price). Calling StockPivot for the row ("ORCL", 41, 42) generates two rows: ("ORCL", "O", 41) and ("ORCL", "C", 42).

Input data for the table function might come from a source such as table StockTable:

CREATE TABLE StockTable ( ticker VARCHAR(4), open_price NUMBER, close_price NUMBER

);

Here are the declarations. See "Returning Results from Table Functions" on page 11-31 for the function bodies.

--Create the types for the table function's output collection

--and collection elements

CREATE TYPE TickerType AS OBJECT

(

ticker VARCHAR2(4), PriceType VARCHAR2(1), price NUMBER

);

/

CREATE TYPE TickerTypeSet AS TABLE OF TickerType;

/

-- Define the ref cursor type

CREATE PACKAGE refcur_pkg IS

TYPE refcur_t IS REF CURSOR RETURN StockTable%ROWTYPE; END refcur_pkg;

/

-- Create the table function

CREATE FUNCTION StockPivot(p refcur_pkg.refcur_t) RETURN TickerTypeSet PIPELINED ... ;

/

Here is an example of a query that uses the StockPivot table function:

11-30 PL/SQL User's Guide and Reference

Setting Up Transformation Pipelines with Table Functions

SELECT * FROM TABLE(StockPivot(CURSOR(SELECT * FROM StockTable)));

In the query above, the pipelined table function StockPivot fetches rows from the CURSOR subquery SELECT * FROM StockTable, performs the transformation, and pipelines the results back to the user as a table. The function produces two output rows (collection elements) for each input row.

Note that when a CURSOR subquery is passed from SQL to a REF CURSOR function argument as in the example above, the referenced cursor is already open when the function begins executing.

Writing a Pipelined Table Function

You declare a pipelined table function by specifying the PIPELINED keyword. This keyword indicates that the function returns rows iteratively. The return type of the pipelined table function must be a collection type, such as a nested table or a varray. You can declare this collection at the schema level or inside a package. Inside the function, you return individual elements of the collection type.

For example, here are declarations for two pipelined table functions. (The function bodies are shown in later examples.)

CREATE FUNCTION GetBooks(cat CLOB) RETURN BookSet_t PIPELINED IS ...;

/

CREATE FUNCTION StockPivot(p refcur_pkg.refcur_t) RETURN TickerTypeSet PIPELINED IS...;

/

Returning Results from Table Functions

In PL/SQL, the PIPE ROW statement causes a table function to pipe a row and continue processing. The statement enables a PL/SQL table function to return rows as soon as they are produced. (For performance, the PL/SQL runtime system provides the rows to the consumer in batches.) For example:

CREATE FUNCTION StockPivot(p refcur_pkg.refcur_t) RETURN TickerTypeSet PIPELINED IS

out_rec TickerType := TickerType(NULL,NULL,NULL); in_rec p%ROWTYPE;

BEGIN LOOP

FETCH p INTO in_rec; EXIT WHEN p%NOTFOUND; -- first row

out_rec.ticker := in_rec.Ticker; out_rec.PriceType := 'O'; out_rec.price := in_rec.OpenPrice; PIPE ROW(out_rec);

-- second row out_rec.PriceType := 'C';

out_rec.Price := in_rec.ClosePrice; PIPE ROW(out_rec);

END LOOP; CLOSE p; RETURN;

END;

/

Tuning PL/SQL Applications for Performance 11-31

Соседние файлы в папке Oracle 10g