NESTED TABLES (Oracle 9i) 中 "RETURN AS VALUE" 的用途是什么

What is the purpose of "RETURN AS VALUE" in NESTED TABLES (Oracle 9i)

是否有特定情况,我应该在什么时候使用RETURN AS VALUE? 通常我只使用 NESTED TABLE xxx STORE AS xxx

例如:

    CREATE OR REPLACE TYPE address_t AS OBJECT (
    ADDID      NUMBER(10,0),
    STREET     VARCHAR2(40),
    ZIP        VARCHAR2(5),
    CITY       VARCHAR2(40)
)
/

CREATE OR REPLACE TYPE addresses_nt AS TABLE OF address_t
/

CREATE OR REPLACE TYPE invoicepos_t AS OBJECT (
    ARTID      NUMBER(10,0),
    AMOUNT     NUMBER(10,0)
)
/

CREATE OR REPLACE TYPE invoicepos_nt AS TABLE OF invoicepos_t
/

CREATE OR REPLACE TYPE customer_t AS OBJECT (
    CUSID      NUMBER(10,0),
    FIRSTNAME  VARCHAR2(30),
    LASTNAME   VARCHAR2(30),
    ADDRESSES  addresses_nt
)
/

CREATE OR REPLACE TYPE invoice_t AS OBJECT (
    INVOICEID  NUMBER(10,0),
    CUSTOMER   REF customer_t,
    ADDID      NUMBER(10,0),
    POSITIONS  invoicepos_nt
)
/

CREATE TABLE customer OF customer_t
    NESTED TABLE ADDRESSES STORE AS all_adresses RETURN AS VALUE    
/

CREATE TABLE invoices OF invoice_t
    NESTED TABLE POSITIONS STORE AS all_invoicepos RETURN AS VALUE
/

据我所知,唯一的区别是 LOCATOR 比 VALUE 快一点。但这没有意义,我希望有人能证明我是错的;几乎从来没有 "fast=true" 开关。


根据 SQL Language Reference:

RETURN [AS] Specify what Oracle Database returns as the result of a query.

    VALUE returns a copy of the nested table itself.

    LOCATOR returns a collection locator to the copy of the nested table.

    The locator is scoped to the session and cannot be used across sessions. Unlike a LOB locator, the collection locator cannot be used to modify the collection instance.

这意味着 LOCATOR 是只读的。但是在 11gR2 上,仍然可以修改 LOCATOR。

Object Relational Developer's Guide 也讨论了 LOCATOR,但没有提到使用它们的任何缺点。

示例架构

CREATE OR REPLACE TYPE invoicepos_t AS OBJECT (
    ARTID      NUMBER(10,0),
    AMOUNT     NUMBER(10,0)
)
/

CREATE OR REPLACE TYPE invoicepos_nt AS TABLE OF invoicepos_t
/

create table invoices_val
(
    INVOICEID  NUMBER,
    POSITIONS  invoicepos_nt
)
    NESTED TABLE POSITIONS STORE AS all_invoicepos_val RETURN AS VALUE
/

create table invoices_loc
(
    INVOICEID  NUMBER,
    POSITIONS  invoicepos_nt
)
    NESTED TABLE POSITIONS STORE AS all_invoicepos_loc RETURN AS locator
/

insert into invoices_val values(1, invoicepos_nt(invoicepos_t(1,1)));
insert into invoices_loc values(1, invoicepos_nt(invoicepos_t(1,1)));
insert into invoices_def values(1, invoicepos_nt(invoicepos_t(1,1)));
commit;

比较性能和功能

--Value: 1.0 seconds
declare
    v_positions invoicepos_nt;
begin
    for i in 1 .. 10000 loop
        select positions
        into   v_positions
        from   invoices_val;
    end loop;

    v_positions.extend;
    v_positions(2) := invoicepos_t(3,3);
    update invoices_val set positions = v_positions;
end;
/

--Locator: 0.8 seconds
declare
    v_positions invoicepos_nt;
begin
    for i in 1 .. 10000 loop
        select positions
        into   v_positions
        from   invoices_loc;
    end loop;

    v_positions.extend;
    v_positions(2) := invoicepos_t(3,3);
    update invoices_loc set positions = v_positions;
end;
/