sql >> Databáze >  >> RDS >> Oracle

Zahrnout hodnotu RowId do vnořené tabulky

ROWID je pseudosloupec , není součástí zobrazení datového slovníku tabulky (neobjevuje se např. v dba_tab_columns ), takže není zahrnuta v %rowtype . Záznam PL/SQL – z čehož vytváříte tabulku PL/SQL – nemá žádné fyzické úložiště, takže žádný skutečný nebo pseudo rowid.

Pokud opravdu chcete uložit ID řádku do záznamu/tabulky, museli byste explicitně deklarovat typ:

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

Pole záznamu nelze volat pouze rowid protože se jedná o datový typ, dal jsem mu předponu data_ ale můžete dát přednost něčemu jinému. A pak musíte použít název pole v těle balíčku, samozřejmě:

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

Mohli byste, jak jste navrhli, uložit celý typ řádku and ID řádku jako dvě pole v typu záznamu:

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

ale kvůli tomu je odkazování na pole trochu trapnější:

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

a pravděpodobně to také znesnadní zaplnění sbírky. Protože stejně musíte znát všechny názvy sloupců/polí, abyste se na ně mohli ve smyčce odkazovat, nejsem si jistý, zda to má velkou výhodu, ale možná vám to přijde přehlednější.

Samozřejmě, že to vůbec předpokládá, že se vaše kolekce naplňuje z podmnožiny dat z tabulky ve stejné DB a sudé relaci, protože rowid řádku se může časem změnit. Můžete se také podívat do forall syntaxe, která nahradí vaše for smyčka, v závislosti na tom, co skutečně děláte. (Měli byste ale také zvážit, zda kolekci vůbec potřebujete – pokud kolekci pouze naplňujete a poté ji používáte pro aktualizaci, pak by jediná aktualizace SQL byla ještě rychlejší...)




  1. Jak opravit:Nebyl nalezen vhodný ovladač pro chybu jdbc:mysql://localhost/dbname při používání fondů?

  2. Jak vytvořím souhrn připojením k jedné tabulce se serverem SQL?

  3. Chyba při použití R k získání přihlašovacích údajů z Windows Cred Vault

  4. mySql zkopíruje řádky do stejné tabulky se změněnou hodnotou klíče (existující nepřepisování)