ROWID
là một cột giả
, nó không phải là một phần của chế độ xem từ điển dữ liệu của bảng (ví dụ:nó không xuất hiện trong dba_tab_columns
), vì vậy nó không được bao gồm trong %rowtype
. Bản ghi PL / SQL - là thứ bạn đang xây dựng bảng PL / SQL - không có bộ nhớ vật lý, vì vậy không có rowid thực hoặc giả.
Nếu bạn thực sự muốn lưu trữ ID hàng trong một bản ghi / bảng, bạn sẽ phải khai báo kiểu một cách rõ ràng:
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;
/
Bạn không thể gọi trường bản ghi chỉ rowid
vì đó là một kiểu dữ liệu, vì vậy tôi đã đặt tiền tố cho nó bằng data_
nhưng bạn có thể thích thứ khác. Và sau đó, bạn cần sử dụng tên trường đó trong phần thân gói của mình, rõ ràng là:
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;
/
Như bạn đã đề xuất, bạn có thể lưu trữ toàn bộ loại hàng và ID hàng dưới dạng hai trường trong loại bản ghi:
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;
/
nhưng điều đó làm cho việc tham chiếu đến các trường trở nên khó khăn hơn một chút:
...
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;
...
và nó có thể sẽ làm cho việc điền bộ sưu tập trở nên khó xử hơn. Vì bạn phải biết tất cả các tên cột / trường để có thể tham chiếu đến chúng trong vòng lặp, tôi không chắc là có nhiều lợi thế, nhưng bạn có thể thấy nó gọn gàng hơn.
Tất nhiên, thực hiện điều này giả sử bộ sưu tập của bạn đang được điền từ một tập hợp con dữ liệu từ bảng trong cùng một DB và phiên thậm chí, vì rowid
của một hàng có thể thay đổi theo thời gian. Bạn cũng có thể muốn xem xét forall
cú pháp để thay thế for
vòng lặp, tùy thuộc vào những gì bạn đang thực sự làm. (Nhưng bạn cũng nên cân nhắc xem bạn có cần bộ sưu tập hay không - nếu bạn chỉ điền bộ sưu tập và sau đó sử dụng bộ sưu tập đó cho bản cập nhật thì một bản cập nhật SQL duy nhất sẽ nhanh hơn ...)