Oracle
 sql >> база данни >  >> RDS >> Oracle

Включете стойността на RowId във вложената таблица

ROWID е псевдоколона , то не е част от изгледа на речника на данните на таблицата (напр. не се показва в dba_tab_columns ), така че не е включен в %rowtype . PL/SQL запис – от който създавате PL/SQL таблица – няма физическо хранилище, така че няма реален или псевдоред.

Ако наистина искате да съхраните идентификатора на реда в запис/таблица, ще трябва изрично да декларирате типа:

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

Не можете да наричате полето за запис просто rowid тъй като това е тип данни, затова го поставих с префикс data_ но може да предпочетете нещо друго. След това трябва да използвате това име на полето в тялото на вашия пакет, очевидно:

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

Можете, както предложихте, да съхраните целия тип ред и ID на реда като две полета в типа запис:

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

но това прави позоваването на полетата малко по-неудобно:

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

и това вероятно ще направи попълването на колекцията също по-неудобно. Тъй като така или иначе трябва да знаете всички имена на колони/полета, за да можете да се позовавате на тях в цикъла, не съм сигурен, че има голямо предимство, но може да ви се стори по-изпипано.

Разбира се, извършването на това изобщо предполага, че вашата колекция се попълва от подмножество от данни от таблицата в същата DB и дори сесия, тъй като rowid на ред може да се промени с времето. Може също да искате да разгледате forall синтаксис, за да замените вашия for цикъл, в зависимост от това какво наистина правите. (Но трябва също така да помислите дали имате нужда от колекцията изобщо - ако просто попълвате колекцията и след това използвате това за актуализацията, тогава една актуализация на SQL ще бъде още по-бърза...)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tomcat jdbc набор от връзки - връщане назад на изоставена транзакция

  2. Изпълнете PL/SQL функция (или процедура) от SQLAlchemy

  3. променете колоната за отпадане на таблицата в базата данни на Oracle

  4. Обединяване на последователни интервали на валидност на датата

  5. Грешки при задействане ORA-04092 ORA-04088