troubleshooting Question

ORA-06531: Reference to uninitialized collection

Avatar of texasreddog
texasreddog asked on
Oracle Database
7 Comments1 Solution8108 ViewsLast Modified:
I am new to PL/SQL and I have a package that executes as part of a job.  When it executes, it fails with the following error:

Low-level errors:
COMP-FO Clean: DBD::Oracle::st execute failed: ORA-06531: Reference to uninitialized collection
ORA-06512: at "FORD_WINS_CLEANER.WINS_COMP_FO", line 143
ORA-06512: at "FORD_WINS_CLEANER.WINS_COMP_FO", line 445

Here is the code of the package:

create or replace package body ford_wins_cleaner.WINS_COMP_FO is

    nInsertInterval constant pls_integer := 100;

    /* cursor getDataFromHeaderTempTable *************************************
    Description:  This cursor gets the data from the temp table

    cursor getDataFromDataTempTable is
        select * from TMP_WINS_PARTS_DATA;

    /* insertHeaderRecord *******************************************

    procedure insertHeaderRecord(headerInsertRecord in TMP_WINS_HEADER_STG_CLNR%rowtype) is
        insert into TMP_WINS_HEADER_STG_CLNR values headerInsertRecord;

    /* insertDetailRecords **************************************************

    procedure loadDetailRecords(partsGUID        in GUID,
                                unpost           in dmi.varchar2s,
                                comp_code        in dmi.varchar2s,
                                invoiceNum       in dmi.varchar2s,
                                winsDate         in dmi.varchar2s,
                                partDetailsTable in out nocopy partDetailsTable_t) is
        i pls_integer;
        k pls_integer;
        i := nvl(partDetailsTable.count, 0) + 1;
        for k in 1 .. invoiceNum.count loop
            partDetailsTable(i).guid := sys_guid();
            partDetailsTable(i).parts_guid := partsGUID;
            if unpost is null then
                partDetailsTable(i).unpost := '';
                partDetailsTable(i).unpost := unpost(k);
            end if;
            if comp_code is null then
                partDetailsTable(i).unpost := '';
                partDetailsTable(i).comp_code := comp_code(k);
            end if;
            partDetailsTable(i).invoice_num := invoiceNum(k);
            partDetailsTable(i).wins_date := to_date(winsDate(k), 'MM-DD-YY');
            i := i + 1;
        end loop;
    end loadDetailRecords;

    /* insertPartsRecord *******************************************
    procedure loadPartsRecords(headerGUID        in GUID,
                               part_num_tab      in dmi.varchar2s,
                               wqty_tab          in dmi.varchar2s,
                               xqty_tab          in dmi.varchar2s,
                               yqty_tab          in dmi.varchar2s,
                               zqty_tab          in dmi.varchar2s,
                               gqty_tab          in dmi.varchar2s,
                               vqty_tab          in dmi.varchar2s,
                               jqty_tab          in dmi.varchar2s,
                               mqty_tab          in dmi.varchar2s,
                               rqty_tab          in dmi.varchar2s,
                               unpost_part       in dmi.varchar2s,
                               comp_code_part    in dmi.varchar2s,
                               invoiceNum_part   in dmi.varchar2s,
                               winsDate_part     in dmi.varchar2s,
                               partsStagingTable in out nocopy partsStagingTable_t,
                               partDetailsTable  in out nocopy partDetailsTable_t) is
        i pls_integer;
        k pls_integer;
        unpost_tab      dmi.varchar2s;
        comp_code_tab   dmi.varchar2s;
        invoice_num_tab dmi.varchar2s;
        wins_date_tab   dmi.varchar2s;
        partsGUID GUID;
        i := nvl(partsStagingTable.count, 0) + 1;
        for k in 1 .. part_num_tab.count loop
            if part_num_tab(k) is not null then
                partsStagingTable(i).guid := sys_guid();
                partsStagingTable(i).header_guid := headerGUID;
                partsStagingTable(i).part_num := part_num_tab(k);
                partsStagingTable(i).wqty := wqty_tab(k);
                partsStagingTable(i).xqty := xqty_tab(k);
                partsStagingTable(i).yqty := yqty_tab(k);
                partsStagingTable(i).zqty := zqty_tab(k);
                partsStagingTable(i).gqty := gqty_tab(k);
                partsStagingTable(i).vqty := vqty_tab(k);
                partsStagingTable(i).jqty := jqty_tab(k);
                partsStagingTable(i).mqty := mqty_tab(k);
                partsStagingTable(i).rqty := rqty_tab(k);
                unpost_tab      := dmi.stringUtil.split('*', unpost_part(k), -1);
                comp_code_tab   := dmi.stringUtil.split('*', comp_code_part(k), -1);
                invoice_num_tab := dmi.stringUtil.split('*', invoiceNum_part(k), -1);
                wins_date_tab   := dmi.stringUtil.split('*', winsDate_part(k), -1);
                -- end if;
                --end if;
                --end loop;
            end if;
            i := i + 1;
        end loop;
    end loadPartsRecords;

    --inserts the data
    procedure processData(partsStagingTable in out nocopy partsStagingTable_t,
                          partDetailsTable  in out nocopy partDetailsTable_t) is
        forall records in 1 .. partsStagingTable.count
            insert into TMP_WINS_PARTS_STG_CLNR values partsStagingTable (records);
        forall record in 1 .. partDetailsTable.count
            insert into TMP_WINS_PART_DETAILS_STG_CLNR values partDetailsTable (record);
    end processData;

    * Splits a clob into a char array.  Equivalent to Perl construct split(//, S, limit).
    * Examples:
    *  splitIntoChars('ABC', 0) = VARCHAR2S('A', 'B', 'C')
    *  splitIntoChars('ABC', 2) = VARCHAR2S('A', 'BC')
    function splitIntoChars(C     in clob,
                            limit in pls_integer) return DMI.VARCHAR2S deterministic is
        result DMI.VARCHAR2S;
        len    pls_integer := DBMS_LOB.getLength(c);
        if 0 < limit and limit < len then
            return splitIntoChars(DBMS_LOB.substr(C, limit, 1), limit);
        end if;
        result := new DMI.VARCHAR2S();
        for I in 1 .. result.count() loop
            result(I) := DBMS_LOB.substr(C, 1, I);
        end loop;
        return result;
    end splitIntoChars;

    function split(pattern in varchar2,
                   S       in clob,
                   limit   in pls_integer) return DMI.VARCHAR2S deterministic is
        --Short-circuit cases
        if s is null then
            return null;
        elsif limit = 1 then
            --if the limit is set to 1 then just return the entire string
            return new DMI.VARCHAR2S(S);
        elsif pattern is null then
            return splitIntoChars(S, limit);
        elsif instr(S, pattern) = 0 then
            return new DMI.VARCHAR2S(S);
        end if;
            item   varchar2(4000);
            items  DMI.VARCHAR2S;
            nStart pls_integer;
            nEnd   pls_integer;
            nCount pls_integer;
            items := DMI.VARCHAR2S();
            items.extend(greatest(limit, 10)); --take it to the limit, we can trim it back later
            nCount := 1;
            items(nCount) := substr(S, 1, instr(S, pattern) - 1);
            --Add items
                nStart := instr(S, pattern, 1, nCount) + 1;
                nEnd   := instr(S, pattern, 1, nCount + 1);
                nCount := nCount + 1;
                if nCount > items.count() then
                    --not enough room, double it in size
                end if;
                if nCount = limit then
                    items(nCount) := substr(S, nStart);
                elsif nEnd > 0 then
                    items(nCount) := substr(S, nStart, nEnd - nStart);
                    --at the end
                    items(nCount) := substr(S, nStart);
                end if;
                --exit if there are no more                
                exit when(nEnd <= 0) or(nEnd is null) or(nCount = limit);
            end loop;
            /* Remove extra allocated fields.
            * Additionally, if LIMIT = 0, strip trailing null fields from the result.
                nTrim pls_integer;
                if (limit = 0) then
                    nTrim := (items.count() - nCount) + 1;
                    nTrim := (items.count() - nCount);
                end if;
                --Now trim off the fields
                if nTrim > 0 then
                end if;
            /* After the trim, items may be empty.  Return null instead of an empty array */
            -- if items.count() = 0 then
            --  return null;
            return items;
            --end if;
    end split;

    /* winsCompFoClean *************************************************
    Description:  This procedure cleans the data from the temp table and
                  moves that data to the staging temp table

    procedure winsCompFOClean(entityGuid in GUID) is
        headerRecord TMP_WINS_HEADER_STG_CLNR%rowtype;
        partsStagingTable partsStagingTable_t := new partsStagingTable_t();
        partDetailsTable partDetailsTable_t := new partDetailsTable_t();
        part_num_tab         dmi.varchar2s;
        wqty_tab             dmi.varchar2s;
        xqty_tab             dmi.varchar2s;
        yqty_tab             dmi.varchar2s;
        zqty_tab             dmi.varchar2s;
        gqty_tab             dmi.varchar2s;
        vqty_tab             dmi.varchar2s;
        jqty_tab             dmi.varchar2s;
        mqty_tab             dmi.varchar2s;
        rqty_tab             dmi.varchar2s;
        unpost_part_tab      dmi.varchar2s;
        comp_code_part_tab   dmi.varchar2s;
        invoice_num_part_tab dmi.varchar2s;
        wins_date_part_tab   dmi.varchar2s;
        headerGuid           GUID;
        procedure ValidateHeaderRecord(rec in TMP_WINS_PARTS_DATA%rowtype) is
            DMI_APP.Assert_UTIL.istrue(rec.pa_code is not null,
                                       'The P&A Code for Cnumber ' || rec.cnumber ||
                                       ' is null.  Please check the record and correct the issue.',
            DMI_APP.Assert_UTIL.istrue(rec.ACCOUNT_LOGON is not null,
                                       'The Account Logon for Cnumber ' || rec.cnumber ||
                                       ' is null.  Please check the record and correct the issue.',
            DMI_APP.Assert_UTIL.istrue(rec.CLAIM_MONTH is not null,
                                       'The Claim Month for Cnumber ' || rec.cnumber ||
                                       ' is null.  Please check the record and correct the issue.',
            DMI_APP.Assert_UTIL.istrue(rec.POLL_MONTH is not null,
                                       'The Poll Month for Cnumber ' || rec.cnumber ||
                                       ' is null.  Please check the record and correct the issue.',
            DMI_APP.Assert_UTIL.istrue(rec.PA_CODE = substr(ia.entities_lib.getEntityID(entityGUID), 3),
                                       'The PA_CODE loaded does not match the Dealer Id : Dealer ID is :' ||
                                       ia.entities_lib.getEntityID(entityGUID) || ': PA_CODE load is : ' || rec.PA_CODE,
        end ValidateHeaderRecord;
        --Gets the correct poll date
        function getPollDate(pollMonth in number) return date is
            pollDate date;
            curDate  date := sysdate;
            pollDate := to_date(pollMonth || '-01' || to_char(sysdate, 'YYYY'), 'MM-DD-YYYY');
            if pollDate > curDate then
                pollDate := to_date(pollMonth || '-' || '01' || '-' || (to_char(sysdate, 'YYYY') - 1), 'MM-DD-YYYY');
            end if;
            return polldate;
        end getPollDate;
        for h in getDataFromDataTempTable loop
            if h.part_num is not null then
                headerRecord.Guid          := sys_guid();
                headerRecord.Owner_Guid    := entityGuid;
                headerRecord.Cnumber       := h.cnumber;
                headerRecord.Dealer_Name   := h.dealer_name;
                headerRecord.Address       := h.address;
                headerRecord.City          :=;
                headerRecord.State         := h.state;
                headerRecord.Zip           :=;
                headerRecord.Account_Logon := h.account_logon;
                headerRecord.Claim_Month   := to_date(h.claim_month, 'HH24:MI:SS  DD MON YYYY');
                headerRecord.Pa_Code       := h.pa_code;
                headerRecord.Poll_Month    := getPollDate(h.poll_month);
                headerRecord.Create_date   := sysdate;
                headerGUID := headerRecord.Guid;
                if (length(regexp_replace(h.wqty, '[A-Za-z0-9\-]')) <= 1 or
                   length(regexp_replace(h.wqty, '[A-Za-z0-9\-]')) is null) then
                    part_num_tab         := new dmi.varchar2s(h.part_num);
                    wqty_tab             := new dmi.varchar2s(h.wqty);
                    xqty_tab             := new dmi.varchar2s(h.xqty);
                    yqty_tab             := new dmi.varchar2s(h.yqty);
                    zqty_tab             := new dmi.varchar2s(h.zqty);
                    gqty_tab             := new dmi.varchar2s(h.gqty);
                    vqty_tab             := new dmi.varchar2s(h.vqty);
                    jqty_tab             := new dmi.varchar2s(h.jqty);
                    mqty_tab             := new dmi.varchar2s(h.mqty);
                    rqty_tab             := new dmi.varchar2s(h.rqty);
                    unpost_part_tab      := new dmi.varchar2s(h.unpost);
                    comp_code_part_tab   := new dmi.varchar2s(h.comp_code);
                    invoice_num_part_tab := new dmi.varchar2s(h.invoice_num);
                    wins_date_part_tab   := new dmi.varchar2s(h.wins_date);
                    part_num_tab         := split(CHR(10), h.part_num, -1);
                    wqty_tab             := split(CHR(10), h.wqty, -1);
                    xqty_tab             := split(CHR(10), h.xqty, -1);
                    yqty_tab             := split(CHR(10), h.yqty, -1);
                    zqty_tab             := split(CHR(10), h.zqty, -1);
                    gqty_tab             := split(CHR(10), h.gqty, -1);
                    vqty_tab             := split(CHR(10), h.vqty, -1);
                    jqty_tab             := split(CHR(10), h.jqty, -1);
                    mqty_tab             := split(CHR(10), h.mqty, -1);
                    rqty_tab             := split(CHR(10), h.rqty, -1);
                    unpost_part_tab      := dmi.stringUtil.split(CHR(10), h.unpost, -1);
                    comp_code_part_tab   := dmi.stringUtil.split(CHR(10), h.comp_code, -1);
                    invoice_num_part_tab := dmi.stringUtil.split(CHR(10), h.invoice_num, -1);
                    wins_date_part_tab   := dmi.stringUtil.split(CHR(10), h.wins_date, -1);
                end if;
                if part_num_tab.count > 0 then
                    if (part_num_tab.count <> wqty_tab.count or part_num_tab.count <> xqty_tab.count or
                       part_num_tab.count <> yqty_tab.count or part_num_tab.count <> zqty_tab.count or
                       part_num_tab.count <> gqty_tab.count or part_num_tab.count <> vqty_tab.count or
                       part_num_tab.count <> jqty_tab.count or part_num_tab.count <> mqty_tab.count or
                       part_num_tab.count <> rqty_tab.count) then
                        dmi.exceptions.raise('Part_Num, and the quantity fields do not have matching counts.  Please check the file.');
                    end if;
                    dmi.exceptions.raise('There are no part records for Account Logon: ' || headerRecord.Account_Logon);
                end if;
            end if;
            if mod(getDataFromDataTempTable%rowcount, nInsertInterval) = 0 then
                processData(partsStagingTable, partDetailsTable);
            end if;
        end loop;
        processData(partsStagingTable, partDetailsTable);
    end winsCompFOClean;

    /* winsCompFoRefresh *******************************************
    Description:  This procedure cleans the data from the temp table and
                  moves that data to the staging temp table

    procedure winsCompFORefresh(updateFlag in varchar2) is
        --Moves the date from the TMP_STG_CLNR to the TMP_STG_VLDB tables
        insert into TMP_WINS_HEADER_STG_VLDB
            select * from TMP_WINS_HEADER_STG_CLNR;
        insert into TMP_WINS_PARTS_STG_VLDB
            select * from TMP_WINS_PARTS_STG_CLNR;
        insert into TMP_WINS_PART_DETAILS_STG_VLDB
            select * from TMP_WINS_PART_DETAILS_STG_CLNR;
        --Moves the data from TMP_STG_VLDB table to the perm tables
    end winsCompFORefresh;


It seems to fail where loadDetailRecords is called, and where that procedure is called in the package.  I am not sure what is uninitialized.  Any help would be appreciated.

Our community of experts have been thoroughly vetted for their expertise and industry experience.

Join our community to see this answer!
Unlock 1 Answer and 7 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 7 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros