Using Oracle Collections

Using Oracle Collections

·

2 min read

You can manipulate complex data types by using Oracle PL/SQL Collections. You can use collections to work with lists of data.

Here is an example of using Oracle Collections.

Create Type

CREATE TYPE MY_CARD AS OBJECT (CARD_NAME VARCHAR2(25),CARD_NUM NUMBER);

CREATE TYPE MY_CARD_NST AS TABLE OF MY_CARD;

Create Table

CREATE TABLE  "MY_WALLET" 
   (    
    "ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE  NOKEEP  NOSCALE  NOT NULL ENABLE, 
    "CARD_TYPE" VARCHAR2(20) COLLATE "USING_NLS_COMP", 
    "NOTES" VARCHAR2(200) COLLATE "USING_NLS_COMP", 
    "CARDS"  "MY_CARD_NST" , 
     CONSTRAINT "MY_WALLET_PK" PRIMARY KEY ("ID")
  USING INDEX  ENABLE
   )  DEFAULT COLLATION "USING_NLS_COMP" 
 NESTED TABLE "CARDS" STORE AS "CARD_STORE_TAB"
 RETURN AS VALUE
/

Insert Demo data

INSERT INTO MY_WALLET (CARD_TYPE) VALUES ('Credit Card');

INSERT INTO MY_WALLET (CARD_TYPE) VALUES ('Library Card');

Create Package

CREATE OR REPLACE PACKAGE MAG_CARD_PKG
IS
    PROCEDURE ADD_CARD_INFO (P_CARD_TYPE_ID NUMBER,P_CARD_NAME VARCHAR2,P_CARD_NUM NUMBER);
    PROCEDURE DISPLAY_CARD_INFO (P_CARD_TYPE_ID NUMBER);

END;

Create Package Body


CREATE OR REPLACE PACKAGE BODY MAG_CARD_PKG
IS
    PROCEDURE ADD_CARD_INFO (P_CARD_TYPE_ID NUMBER,P_CARD_NAME VARCHAR2,P_CARD_NUM NUMBER)
    IS
        V_CARD_INFO MY_CARD_NST;
        I INTEGER;
    BEGIN
        SELECT CARDS INTO V_CARD_INFO FROM MY_WALLET WHERE ID = P_CARD_TYPE_ID;
        -- if card exist
        IF V_CARD_INFO.EXISTS(1) THEN
            I := V_CARD_INFO.LAST;
            -- add a new card after this
            V_CARD_INFO.EXTEND(1);
            V_CARD_INFO(I+1) := MY_CARD(P_CARD_NAME,P_CARD_NUM);
            UPDATE MY_WALLET SET CARDS=V_CARD_INFO WHERE ID=P_CARD_TYPE_ID;
        ELSE
            -- if no card exist, add this card
            UPDATE MY_WALLET SET CARDS=MY_CARD_NST(MY_CARD(P_CARD_NAME,P_CARD_NUM)) WHERE ID=P_CARD_TYPE_ID;
        END IF;
    END;

    PROCEDURE DISPLAY_CARD_INFO (P_CARD_TYPE_ID NUMBER)
    IS
        V_CARD_INFO MY_CARD_NST;
        I INTEGER;
    BEGIN
        SELECT CARDS INTO V_CARD_INFO FROM MY_WALLET WHERE ID=P_CARD_TYPE_ID;
        -- if card exist
        IF V_CARD_INFO.EXISTS(1) THEN
            -- loop all cards
            FOR IDX IN V_CARD_INFO.FIRST..V_CARD_INFO.LAST LOOP
                -- print this card
                HTP.P('MY CARD NAME:' || V_CARD_INFO(IDX).CARD_NAME || ', CARD NO: ' || V_CARD_INFO(IDX).CARD_NUM );
            END LOOP;
        ELSE
            HTP.P('NO SUCH TYPE OF CARD IN MY WALLET.');
        END IF;
    END;

END;

Add and Display Collections Data

BEGIN
    -- card type 1 (Credit Card)
    MAG_CARD_PKG.ADD_CARD_INFO(1,'AIB',1111111111);
    MAG_CARD_PKG.ADD_CARD_INFO(1,'BOI',2222222222);
    -- card type 2 (Library Card)
    MAG_CARD_PKG.ADD_CARD_INFO(2,'Central Library',3333333333);
    -- Show all cards with card type 1 (Credit Card)
    MAG_CARD_PKG.DISPLAY_CARD_INFO(1);
END;

SQL show all Collections Data

SELECT C1.ID,C1.CARD_TYPE,C2.*  FROM MY_WALLET C1,TABLE(C1.CARDS) C2 ORDER BY C1.ID

The results are as follows:

image.png