sql >> Database >  >> RDS >> Oracle

RowId-waarde opnemen in geneste tabel

ROWID is een pseudokolom , het maakt geen deel uit van de datadictionary-weergave van de tabel (het verschijnt bijvoorbeeld niet in dba_tab_columns ), dus het is niet opgenomen in de %rowtype . Een PL/SQL-record - waar u een PL/SQL-tabel van maakt - heeft geen fysieke opslag, dus geen echte of pseudo-rowid.

Als u de rij-ID echt in een record/tabel wilt opslaan, moet u het type expliciet declareren:

create or replace package dat_pkg is

    type typ_dat_rec is record (
        data_id     data_test.data_id%type,
        data_value  data_test.data_value%type,
        data_rowid  rowid);

    type typ_dat_tst is table of data_test%rowtype index by pls_integer;

    procedure proc_test (p_dat  typ_dat_tst);

end dat_pkg;
/

Je kunt het recordveld niet gewoon rowid noemen aangezien dat een gegevenstype is, heb ik het voorafgegaan door data_ maar misschien heb je liever iets anders. En dan moet je die veldnaam natuurlijk in de body van je pakket gebruiken:

create or replace package body dat_pkg is

    procedure proc_test (p_dat  typ_dat_tst)
    is
    begin

        for i in 1..p_dat.count loop

            update  data_test        
            set     data_value  = p_dat(i).data_value  
            where   data_id     = p_dat(i).data_id
            and     rowid       = p_dat(i).data_rowid;

        end loop;

    end proc_test;

end dat_pkg;
/

Je zou, zoals je voorstelde, het hele rijtype en . kunnen opslaan de rij-ID als twee velden in het recordtype:

create or replace package dat_pkg is

    type typ_dat_rec is record (
        data_rec    data_test%rowtype,
        data_rowid  rowid);

    type typ_dat_tst is table of typ_dat_rec index by pls_integer;

    procedure proc_test (p_dat  typ_dat_tst);

end dat_pkg;
/

maar dat maakt het verwijzen naar de velden wat lastiger:

...
        for i in 1..p_dat.count loop

            update  data_test        
            set     data_value  = p_dat(i).data_rec.data_value  
            where   data_id     = p_dat(i).data_rec.data_id
            and     rowid       = p_dat(i).data_rowid;

        end loop;
...

en het zal het vullen van de collectie waarschijnlijk ook lastiger maken. Omdat je toch alle kolom-/veldnamen moet kennen om er in de loop naar te kunnen verwijzen, weet ik niet zeker of er veel voordeel is, maar misschien vind je het netter.

Als u dit doet, gaat u er natuurlijk van uit dat uw verzameling wordt gevuld met een subset van gegevens uit de tabel in dezelfde DB en zelfs in dezelfde sessie, aangezien de rowid van een rij kan in de loop van de tijd veranderen. Misschien wil je ook kijken naar de forall syntaxis om uw for . te vervangen lus, afhankelijk van wat je echt aan het doen bent. (Maar je moet ook overwegen of je de collectie wel nodig hebt - als je alleen de collectie vult en die vervolgens voor de update gebruikt, dan zou een enkele SQL-update nog sneller zijn...)




  1. Delphi - MySQL Beste databewuste componenten om te gebruiken

  2. Doorloop de tabel, voer een berekening uit op elke rij

  3. toestemming geweigerd proberen om een ​​csv-bestand te lezen met behulp van JDBC voor postgres-database

  4. Postgres groeperen op zoekopdracht