ROWID
is a pseudocolumn, es ist nicht Teil der Data Dictionary-Ansicht der Tabelle (z. B. erscheint es nicht in dba_tab_columns
), so ist es nicht in der %rowtype
enthalten. Ein PL/SQL-Datensatz - woran Sie eine PL/SQL-Tabelle erstellen - hat keinen physischen Speicher, also keine echte oder Pseudo-Rowid.
Wenn Sie wirklich die Zeilen-ID in einem Datensatz/Tabelle speichern möchten, würden Sie den Typ explizit erklären müssen:
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 wie das nur rowid
nennen, ist ein Datentyp , also habe ich es mit data_
vorangestellt, aber Sie bevorzugen vielleicht etwas anderes. Und dann müssen Sie in Ihrem Paket Körper, dass die Feldnamen verwenden, offensichtlich:
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, speichern Sie den gesamten Zeilentyp und der Zeilen-ID als zwei Felder in dem 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 auf die Felder unter Bezugnahme etwas umständlich:
...
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 die Sammlung mehr make a bevöl wkward auch. Da Sie sowieso alle Spalten-/Feldnamen kennen müssen, um sich auf sie in der Schleife beziehen zu können, bin ich mir nicht sicher, ob das von Vorteil ist, aber Sie finden es vielleicht besser.
Natürlich wird davon ausgegangen, dass Ihre Sammlung aus einer Teilmenge von Daten aus der Tabelle in der gleichen DB und sogar in der Sitzung gefüllt wird, da sich die Zeile rowid
einer Zeile ändern kann. Vielleicht möchten Sie auch in die forall
-Syntax suchen, um Ihre for
-Schleife zu ersetzen, je nachdem, was Sie wirklich tun. (Aber Sie sollten auch überlegen, ob Sie die Sammlung überhaupt benötigen - wenn Sie nur die Sammlung füllen und dann für das Update verwenden, wäre ein einzelnes SQL-Update noch schneller ...)
wäre es besser, wenn ich definiert es als unten? Typ typ_dat_rec ist Datensatz ( data_rec data_test% rowtype, data_rowid rowid); –
Ich sehe nicht, dass das wirklich besser wäre, aber hängt vielleicht davon ab, wie Sie es benutzen. Es würde funktionieren, aber Sie würden eine andere Kennung haben, wenn Sie es verwenden, und es macht das Auffüllen der Sammlung schwieriger. –
Danke für das Hinzufügen des Vorschlags, der Grund, warum ich die Verwendung eines '% rowType 'vorgeschlagen habe, war, weil ich ungefähr 100 Spalten in dieser Tabelle habe und es wäre etwas" unordentlich "für mich, sie in der Typspezifikation zu deklarieren. –