sql >> Databasteknik >  >> RDS >> Oracle

Inkludera RowId-värde i kapslad tabell

ROWID är en pseudokolumn , det är inte en del av datalexikonet i tabellen (det visas t.ex. inte i dba_tab_columns ), så det ingår inte i %rowtype . En PL/SQL-post - vilket är vad du konstruerar en PL/SQL-tabell av - har ingen fysisk lagring, så ingen riktig eller pseudo-rowid.

Om du verkligen vill lagra rad-ID i en post/tabell måste du uttryckligen deklarera typen:

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;
/

Du kan inte anropa postfältet bara rowid eftersom det är en datatyp, så jag har prefixet den med data_ men du kanske föredrar något annat. Och sedan måste du använda det fältnamnet i paketets kropp, uppenbarligen:

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;
/

Du kan, som du föreslog, lagra hela radtypen och rad-ID:t som två fält i posttypen:

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;
/

men det gör hänvisningen till fälten lite mer besvärlig:

...
        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;
...

och det kommer förmodligen också att göra det svårare att fylla samlingen. Eftersom du ändå måste känna till alla kolumn-/fältnamn för att kunna referera till dem i slingan är jag inte säker på att det finns någon större fördel, men du kanske tycker att det är snyggare.

Att göra detta överhuvudtaget förutsätter naturligtvis att din samling fylls på från en delmängd av data från tabellen i samma DB och jämna session, eftersom en rads rowid kan förändras över tiden. Du kanske också vill titta på forall syntax för att ersätta din for loop, beroende på vad du verkligen gör. (Men du bör också överväga om du behöver samlingen överhuvudtaget - om du bara fyller i samlingen och sedan använder den för uppdateringen så skulle en enda SQL-uppdatering vara snabbare...)




  1. Enkel syntax för 'skapa tabell från vy' i mysql?

  2. Långsam prestanda på Hibernate + Java men snabb när jag använder TOAD med samma inbyggda Oracle-fråga

  3. Hur man får SQL-text från Postgres händelseutlösare

  4. Optimeringsfråga:DBMS_METADATA.GET_DDL (Oracle)