ROWID
ist eine Pseudospalte
, ist es nicht Teil der Datenwörterbuchansicht der Tabelle (z. B. erscheint es nicht in dba_tab_columns
), also ist es nicht in %rowtype
enthalten . Ein PL/SQL-Datensatz – aus dem Sie eine PL/SQL-Tabelle erstellen – hat keinen physischen Speicher, also keine echte oder Pseudo-Rowid.
Wenn Sie die Zeilen-ID wirklich in einem Datensatz/einer Tabelle speichern möchten, müssen Sie den Typ explizit deklarieren:
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;
/
Sie können das Datensatzfeld nicht einfach rowid
nennen Da es sich um einen Datentyp handelt, habe ich ihm data_
vorangestellt aber vielleicht bevorzugst du etwas anderes. Und dann müssen Sie diesen Feldnamen natürlich in Ihrem Paketkörper verwenden:
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;
/
Sie könnten, wie Sie vorgeschlagen haben, den gesamten Zeilentyp und speichern die Zeilen-ID als zwei Felder im Datensatztyp:
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;
/
aber das macht den Bezug auf die Felder etwas umständlicher:
...
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;
...
und es wird wahrscheinlich auch das Auffüllen der Sammlung umständlicher machen. Da Sie sowieso alle Spalten-/Feldnamen kennen müssen, um in der Schleife auf sie verweisen zu können, bin ich mir nicht sicher, ob es einen großen Vorteil gibt, aber Sie finden es vielleicht übersichtlicher.
Wenn Sie dies überhaupt tun, wird natürlich davon ausgegangen, dass Ihre Sammlung aus einer Teilmenge von Daten aus der Tabelle in derselben Datenbank und sogar in derselben Sitzung gefüllt wird, da die rowid
einer Zeile können sich im Laufe der Zeit ändern. Vielleicht möchten Sie auch in forall
nachsehen Syntax zum Ersetzen Ihres for
Schleife, je nachdem, was Sie wirklich tun. (Aber Sie sollten auch überlegen, ob Sie die Sammlung überhaupt brauchen - wenn Sie nur die Sammlung füllen und diese dann für das Update verwenden, dann wäre ein einzelnes SQL-Update noch schneller ...)