Search This Blog

Tuesday, June 24, 2025

How do I Create and use a pipelined function

 Creating and Using a Pipelined Function in Oracle APEX

A pipelined function in Oracle is a special type of function that returns a table of data row-by-row instead of all at once. This improves performance and memory efficiency, especially for large datasets.

Pipelined functions are commonly used in reports, data processing, and transformations in Oracle APEX. This tutorial covers how to create and use a pipelined function effectively.


What is a Pipelined Function?

A pipelined function processes and returns data incrementally as it is being generated. It does this by using the PIPELINED keyword and PIPE ROW statements to return each row dynamically.

Advantages of Pipelined Functions

  • Improved Performance – Processes rows one at a time instead of loading all data into memory.

  • Efficient for Large Datasets – Works well with millions of rows by streaming results.

  • Seamless Integration – Can be used in SQL queries, reports, and APIs.


Steps to Create a Pipelined Function

Step 1: Define a Table Type

Before creating the function, define a table type that represents the structure of the data being returned.

CREATE OR REPLACE TYPE t_employee AS OBJECT (

    emp_id NUMBER,

    emp_name VARCHAR2(100),

    emp_salary NUMBER

);

/


CREATE OR REPLACE TYPE t_employee_table AS TABLE OF t_employee;

/

This defines:

  • t_employee – An object representing an employee with ID, name, and salary.

  • t_employee_table – A collection (table) type to hold multiple employees.

 

Step 2: Create the Pipelined Function

The function retrieves employees and returns the data row by row.

CREATE OR REPLACE FUNCTION get_high_salary_employees (

    p_min_salary NUMBER

) RETURN t_employee_table PIPELINED IS

BEGIN

    FOR emp_rec IN (

        SELECT emp_id, emp_name, emp_salary 

        FROM employees 

        WHERE emp_salary > p_min_salary

    ) LOOP

        PIPE ROW (t_employee(emp_rec.emp_id, emp_rec.emp_name, emp_rec.emp_salary));

    END LOOP;

    

    RETURN;

END get_high_salary_employees;

/

How This Function Works

  • Takes an input parameter (p_min_salary) to filter employees based on salary.

  • Loops through the employee records that meet the condition.

  • Uses PIPE ROW to return each row immediately instead of waiting for all data to be processed.

  • Ends with RETURN; to complete execution.

 

Using the Pipelined Function in APEX

1. Using the Function in a SQL Query for Reports

You can call the function inside a SELECT statement to retrieve employees dynamically.

SELECT * FROM TABLE(get_high_salary_employees(5000));

This returns all employees with a salary greater than 5000 and can be used in an Interactive Report or Classic Report in Oracle APEX.

 

2. Creating a Report in APEX with a Pipelined Function

  1. Go to APEX Page Designer

  2. Add a Classic or Interactive Report

  3. Set the SQL Query as: 

SELECT * FROM TABLE(get_high_salary_employees(:P1_MIN_SALARY));

  1. Create a page item (P1_MIN_SALARY) to allow users to input the minimum salary.

  2. Run the page and enter a value in P1_MIN_SALARY to filter results dynamically.

 

3. Using the Function in a PL/SQL Process

Pipelined functions can also be used in PL/SQL processes inside APEX.

DECLARE

    v_employee_list t_employee_table;

BEGIN

    v_employee_list := get_high_salary_employees(:P1_MIN_SALARY);

    

    FOR i IN 1..v_employee_list.COUNT LOOP

        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_employee_list(i).emp_name || ', Salary: ' || v_employee_list(i).emp_salary);

    END LOOP;

END;

This PL/SQL block calls the function and loops through the returned employees.

 

4. Using a Pipelined Function in a RESTful Web Service

Oracle APEX supports RESTful Web Services, which can return pipelined function data as JSON.

  1. Create a RESTful Web Service in APEX

  2. Set the SQL Query as: 

SELECT * FROM TABLE(get_high_salary_employees(:P1_MIN_SALARY));

  1. Expose the service to return data in JSON format.

Example JSON response:

[

    { "EMP_ID": 101, "EMP_NAME": "Alice", "EMP_SALARY": 6000 },

    { "EMP_ID": 102, "EMP_NAME": "Bob", "EMP_SALARY": 7000 }

]

 

Best Practices for Using Pipelined Functions in APEX

  • Use Appropriate Data Types – Ensure the table type matches the expected data structure.

  • Optimize Queries – Add indexes and use efficient filtering to improve performance.

  • Handle Exceptions – Prevent runtime errors by using BEGIN...EXCEPTION...END.

Example with Exception Handling

CREATE OR REPLACE FUNCTION get_high_salary_employees_safe (

    p_min_salary NUMBER

) RETURN t_employee_table PIPELINED IS

BEGIN

    FOR emp_rec IN (

        SELECT emp_id, emp_name, emp_salary FROM employees 

        WHERE emp_salary > p_min_salary

    ) LOOP

        PIPE ROW (t_employee(emp_rec.emp_id, emp_rec.emp_name, emp_rec.emp_salary));

    END LOOP;

    

    RETURN;

EXCEPTION

    WHEN NO_DATA_FOUND THEN

        DBMS_OUTPUT.PUT_LINE('No employees found.');

    WHEN OTHERS THEN

        DBMS_OUTPUT.PUT_LINE('Unexpected error.');

END get_high_salary_employees_safe;

/

This ensures the function does not fail unexpectedly if no records are found or if an error occurs.

 

Pipelined functions in Oracle APEX allow efficient data retrieval row by row, improving performance and usability in reports, PL/SQL processes, and RESTful services.



How do I Create and use a non-pipelined function

 Creating and Using a Non-Pipelined Function in Oracle APEX

In Oracle APEX, functions play a vital role in processing data, performing calculations, and returning results for use in reports, validations, and dynamic computations. A non-pipelined function is a standard PL/SQL function that returns a single value or a collection (such as a table or record) without streaming results row-by-row like a pipelined function.

This tutorial explains how to create and use a non-pipelined function in Oracle APEX, providing examples and best practices.


What is a Non-Pipelined Function?

A non-pipelined function is a regular PL/SQL function that:

  • Processes data and returns a single value, a record, or a collection.

  • Does not use the PIPELINED keyword (which streams data row-by-row).

  • Can be used in SQL queries, PL/SQL processes, APEX computations, validations, and dynamic actions.


Creating a Non-Pipelined Function

A basic non-pipelined function returns a single value.

Example 1: Simple Function Returning a Value

This function calculates the total price of an order based on quantity and unit price.

CREATE OR REPLACE FUNCTION get_total_price (

    p_quantity NUMBER,

    p_unit_price NUMBER

) RETURN NUMBER IS

    v_total NUMBER;

BEGIN

    v_total := p_quantity * p_unit_price;

    RETURN v_total;

END get_total_price;

/

How to Use in APEX

  1. In a SQL Query (for Reports or Forms)

SELECT order_id, get_total_price(quantity, unit_price) AS total_price

FROM orders;

In PL/SQL Process (e.g., After Submit Button Click)

DECLARE

    v_total NUMBER;

BEGIN

    v_total := get_total_price(:P1_QUANTITY, :P1_UNIT_PRICE);

    :P1_TOTAL := v_total;  -- Assigning result to a page item

END;

  1. In a Validation (To Ensure Price is Reasonable)

IF get_total_price(:P1_QUANTITY, :P1_UNIT_PRICE) > 1000 THEN

    RETURN 'Total price cannot exceed 1000.';

END IF;


Returning a Record from a Non-Pipelined Function

A function can return a record type, such as customer details.

Example 2: Returning a Record (Single Row of Data)

CREATE OR REPLACE FUNCTION get_customer_info (

    p_customer_id NUMBER

) RETURN customers%ROWTYPE IS

    v_customer customers%ROWTYPE;

BEGIN

    SELECT * INTO v_customer FROM customers WHERE customer_id = p_customer_id;

    RETURN v_customer;

END get_customer_info;

/


How to Use in APEX

  1. In a PL/SQL Process to Fill Page Items

DECLARE

    v_customer customers%ROWTYPE;

BEGIN

    v_customer := get_customer_info(:P1_CUSTOMER_ID);

    :P1_CUSTOMER_NAME := v_customer.customer_name;

    :P1_CUSTOMER_EMAIL := v_customer.email;

END;

Using in a Report

SELECT c.customer_id, c.customer_name, c.email 

FROM customers c

WHERE c.customer_id = (SELECT customer_id FROM get_customer_info(:P1_CUSTOMER_ID));


Returning a Table from a Non-Pipelined Function

A function can return a table of data, which is useful for reports.

Example 3: Returning a Collection (Table Type Data)

  1. Define a Table Type

CREATE OR REPLACE TYPE t_order_table AS TABLE OF orders%ROWTYPE;

/

Create the Function to Return the Collection

CREATE OR REPLACE FUNCTION get_orders_by_customer (

    p_customer_id NUMBER

) RETURN t_order_table IS

    v_orders t_order_table;

BEGIN

    SELECT CAST(COLLECT(o) AS t_order_table)

    INTO v_orders

    FROM orders o

    WHERE o.customer_id = p_customer_id;

    

    RETURN v_orders;

END get_orders_by_customer;

/

How to Use in APEX

  1. Using in SQL Query (For a Report Region)

  2. SELECT * FROM TABLE(get_orders_by_customer(:P1_CUSTOMER_ID));

  3. Using in a Process to Store Data in Collections

DECLARE

    v_orders t_order_table;

BEGIN

    v_orders := get_orders_by_customer(:P1_CUSTOMER_ID);

    FOR i IN 1..v_orders.COUNT LOOP

        DBMS_OUTPUT.PUT_LINE('Order ID: ' || v_orders(i).order_id);

    END LOOP;

END;


Best Practices for Using Non-Pipelined Functions in APEX

  • Use Page Items as Parameters – When calling functions from APEX, pass page items (:P1_ITEM) as arguments.

  • Optimize for Performance – Avoid returning large datasets, as it can slow down reports.

  • Handle NULL Values – Ensure the function handles missing values gracefully.

  • Use Exception Handling – Prevent runtime errors by handling exceptions inside the function.

Example with Exception Handling:

CREATE OR REPLACE FUNCTION get_product_price (

    p_product_id NUMBER

) RETURN NUMBER IS

    v_price NUMBER;

BEGIN

    SELECT price INTO v_price FROM products WHERE product_id = p_product_id;

    RETURN v_price;

EXCEPTION

    WHEN NO_DATA_FOUND THEN

        RETURN NULL;  -- Return NULL if no product is found

    WHEN OTHERS THEN

        RETURN -1;  -- Return -1 for unexpected errors

END get_product_price;

/


Non-pipelined functions are a powerful tool in Oracle APEX for performing calculations, retrieving records, and returning tables of data. They can be used in SQL queries, PL/SQL processes, reports, validations, and dynamic actions to enhance application functionality.


UI Defaults

 In Oracle APEX, User Interface (UI) Defaults are a set of metadata-driven, table- and column-scoped attributes that APEX consults when it g...