Search This Blog

Tuesday, June 24, 2025

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.


No comments:

Post a Comment

Learning ORACLE APEX: Creating a Complete Application from a CSV File

  Learning ORACLE APEX: Creating a Complete Application from a CSV File Start with a simple CSV dataset and finish with a working, shareable...