not a pretty sight - PL/SQL global private elements

From: Wayne Stewart <wayne.stewart_at_mci.com>
Date: 1996/12/06
Message-ID: <32A84FF6.2932_at_mci.com>


[Quoted] Hidee again, folks,

[Quoted] We have a buggy problem today, pertaining to private global package elements in PL/SQL. It looks as though we've run into a bug with the persistence (or lack of same) for those supposedly "global" elements:

Seems as though they pop into and out of existence according to hermeneutic rules not found in the textbooks.    

For those elite and unfortunate few of you who might know about such PL/SQL arcana, I append sections of the code with explanations below.

I'd appreciate any comments; and I apologize for the length of this bothersome document.

> "If I'd had more time, I would have written you a shorter letter."

>                                                            -- Pascal

Thank ye,

--

Wayne Stewart
MCI - Campbell Creek

tel:    972-918-7009
vnet:   777-7009
fax:    972-918-6097

--

My package has a private global record, EQUIP_REC. EQUIP_REC contains 7 arrays of equipment information.

So EQUIP_REC(1) is the first record, storing 7 pieces of information about that first equipment.

EQUIP_REC(2) is the second record.

EQUIP_REC(3) is the third record.

And so on.

Now 3 separate procedures in this package need to use EQUIP_REC. For this reason it is a private global record. Its record_type declaration, EQUIPMENT_RECORDTYPE, is in the package specification. And its instance, EQUIP_REC, is declared in the package body before the first procedure. The declarations look like this:



CREATE or REPLACE package ENTER_EVENT
IS

< 7 array type declarations go here... >

  • RECORD type for storing equipment entries before final submission
        type    equipment_recordtype
                is record
                (
                site    site_array_tabletype,
                equip   equip_array_tabletype,
                lalpha  low_alpha_array_tabletype,
                halpha  high_alpha_array_tabletype,
                mux     mux_array_tabletype,
                lslot   low_slot_array_tabletype,
                hslot   high_slot_array_tabletype
                );

< After this specification section, I create a private instance of the record_type in the package body.... >

CREATE or REPLACE package body ENTER_EVENT IS

  • Global variables
    • record of arrays of eqpt entered via procedure 'enter_4'

        equip_rec equipment_recordtype;

< Then the first procedure goes here... >



3 procedures call this EQUIP_REC private global record, and I list relevant sections from all 3 below. The 3 procedures are:

        ENTER_4         SUBMIT_4         and

        ENTER_5. ENTER_4 prints out the number of the LAST EQUIP_REC array element populated, as a visual debug.

SUBMIT_4 populates EQUIP_REC record elements with field variables.

         Afterwards, if the user has pressed a 'More' submit button,     SUBMIT_4 calls ENTER_4 again so that the user can enter more records.

         This loop continues until the user has entered all the records into the

    record array. Then the user presses 'Complete', and SUBMIT_4 moves on to

    the ENTER_5 procedure.

ENTER_5 just prints all the EQUIP_REC records on screen.

--

As you can see from the logic above, there are 2 paths of action the user can take:

--

PATH ONE The user can:

        enter one list of equipment in ENTER_4,
        press 'Complete',
        and view the result in ENTER_5.

PATH TWO The user can:

        enter one list of equipment in ENTER_4,
        press 'More',
        enter more lists of equipment in ENTER_4 ( repeatedly looping
back to
              it with 'More' button ),
        press 'Complete',
        and view the result in ENTER_5.

--

HERE'S WHERE THE MOUSETRAP GAME MALFUNCTIONS. %-)


If the user follows PATH ONE everything works OK. All 3 procedures see EQUIP_REC, and the user can review his list of equipment in ENTER_5.

However, if the user follows PATH TWO, not everything works OK. ENTER_4 and SUBMIT_4 work OK, but ENTER_5 does NOT. ENTER_5 does NOT see EQUIP_REC. It skips the EQUIP_REC print loop, and prints out the default dummy debug text, namely:

> 'I HAVE COMPLETELY FORGOTTEN ABOUT EQUIP_REC!'
--

It seems like a PL/SQL bug to me ( v2.3 on NT Oracle RDBMS 7.3.2.2.0 ).

But I may have done something wrong myself. It's happened before. :-)

Here are the important sections of each of the 3 procedures mentioned previously. Thanks for taking time to review the code: I think it's darn tedious, myself. But maybe a guru can see my mistake just by skimming through it.



PROCEDURE enter_4 ( < some input parameters... > )

< Declare some variables... >

BEGIN < Print some stuff... >

        htp.p ( 'last element in equip_rec is ' || equip_rec.equip.last );



PROCEDURE submit_4 ( < some input parameters... > )

< Declare some variables... >

BEGIN < Print some stuff... >

  • Enter fields into equip_rec, whether submit='More' or submit='Complete'
        IF (    t_stn1 IS NOT NULL
                AND
                t_equip1 IS NOT NULL
                AND
                t_lalpha1 IS NOT NULL
                )     -- we have enough info for a properly-formed
equipment record
        THEN
                i := i + 1;          -- next record array element
                equip_rec.site(i) := t_stn1;
                equip_rec.equip(i) := t_equip1;
                equip_rec.lalpha(i) := t_lalpha1;
                equip_rec.halpha(i) := t_halpha1;
                equip_rec.mux(i) := t_mux1;
                equip_rec.lslot(i) := t_lslot1;
                equip_rec.hslot(i) := t_hslot1;
        END IF;

        IF (    t_stn2 IS NOT NULL
                        AND
                        t_equip2 IS NOT NULL
                        AND
                        t_lalpha2 IS NOT NULL
                ) -- we have enough info for a properly-formed equipment
record
        THEN
                i := i + 1;  -- next record array element
                equip_rec.site(i) := t_stn2;
                equip_rec.equip(i) := t_equip2;
                equip_rec.lalpha(i) := t_lalpha2;
                equip_rec.halpha(i) := t_halpha2;
                equip_rec.mux(i) := t_mux2;
                equip_rec.lslot(i) := t_lslot2;
                equip_rec.hslot(i) := t_hslot2;
        END IF;

        < etc... More elements get populated... >


-- If user requests more equipment, loop back to ENTER_4 again.
-- If user states that the list of equipment is complete, move on
to
-- ENTER_5 procedure.
IF submit = 'More' THEN enter_event.enter_4 ( < some parameters > ); ELSIF submit = 'Complete' THEN enter_event.enter_5 ( < some parameters > ); END IF;
----------------------------------------------------------------
----------------------------------------------------------------

PROCEDURE enter_5 ( < some parameters > )

< Declare some variables... >

BEGIN < Print some stuff... >

  • Display all equipments specified in equip_rec.
        IF equip_rec.equip.last > 0    -- we have 1 or more records
        THEN

                htp.tableOpen ( '0', 'LEFT' );

                FOR row IN 1 .. enter_event.equip_rec.equip.last
                LOOP
                        htp.tableRowOpen;
                        htp.tableData ( enter_event.equip_rec.site(row)
);
                        htp.tableData ( enter_event.equip_rec.equip(row)
);
                        htp.tableData (
enter_event.equip_rec.lalpha(row) );
                        htp.tableData (
enter_event.equip_rec.halpha(row) );
                        htp.tableData ( enter_event.equip_rec.mux(row)
);
                        htp.tableData ( enter_event.equip_rec.lslot(row)
);
                        htp.tableData ( enter_event.equip_rec.hslot(row)
);
                        htp.tableRowClose;
                END LOOP;

                htp.tableClose;
        ELSE
                htp.p ( 'I HAVE COMPLETELY FORGOTTEN ABOUT EQUIP_REC!'
);
        END IF;


----------------------------------------------------------------
----------------------------------------------------------------

Thanks again for taking a look at my buggy code. Maybe I can return the favor if you have a PL/SQL-specific question in future.

And please, go ahead and help yourself to the M&M jar outside my cube.

:-)

Best regards,

--

Wayne Stewart
MCI - Campbell Creek

tel:    972-918-7009
vnet:   777-7009
fax:    972-918-6097
Received on Fri Dec 06 1996 - 00:00:00 CET

Original text of this message