引用数组值

Referencing array values

我遇到了以下问题。

create type some_ty as object(
s_id number
);

create table some_tbl of some_ty;

insert into some_tbl values(1);
insert into some_tbl values(2);
insert into some_tbl values(3);

create type some_arr as varray(5) of number;

create type test_ty as object(
t_id number,
array some_arr
) ;

create table test_tbl of test_ty;

insert into test_tbl values(10, some_arr(1,2,3,4));

我的问题是是否有 sql 方法来检查 some_arr 的值是否存在于 some_tbl 中?因为现在它也插入了“4”,这不是 some_tbl.

的记录

我不能在 varray 上使用 ref。

我已经设法使用 pl/sql 循环来做到这一点。我只是想知道有没有简单的方法。

解决这个问题的一种方法是将查找封装到构造函数中。

create or replace type test_ty as object(
  t_id number,
  array some_arr ,
  constructor function test_ty (self in out test_ty
             , t_id number
             , array some_arr)  
    return self as result        
) ;
/

create or replace type body test_ty as 

  constructor function test_ty (self in out test_ty
             , t_id number
             , array some_arr)  
    return self as result        
    is
        n number;
    begin
        for idx in array.first() .. array.last
        loop
            select s_id into n
            from some_tbl
            where s_id = array(idx);
        end loop;
        self.t_id := t_id;
        self.array := array;
        return;         
    exception 
        when no_data_found then
           raise_application_error(-20099, 'array contains invalid value');     
    end test_ty ;
end ;
/

调用方法如下:

SQL> insert into test_tbl values(test_ty(9, some_arr(1,2,3)));

1 row created.

SQL> insert into test_tbl values(test_ty(10, some_arr(1,2,3,4)));
insert into test_tbl values(test_ty(10, some_arr(1,2,3,4)))
                            *
ERROR at line 1:
ORA-20099: array contains invalid value
ORA-06512: at "FOX.TEST_TY", line 21


SQL> 

请注意,您需要显式使用类型来调用构造函数:

SQL> insert into test_tbl values(10, some_arr(1,2,3,4));

1 row created.

SQL> 

"Example student and class. one class can have maximum 10 students. and with many-many table i cannot do that."

嗯,你可以这样做:

create table class_student (
    class_id number not null 
    , student_id number not null 
    , attendee_no number(2,0) not null 
    , constraint class_student_pk 
        primary key (class_id, student_id, attendee_no) 
    , constraint class_student_ck
        check (attendee_no between 1 and 10 ) 
    , constraint class_student_class_fk 
        foreign key (class_id) references class 
    , constraint class_student_student_fk 
        foreign key (student_id) references student
);

如果您使用的是 Object-Relational database and want to to have a reference to another object then use a REF。您可以在 VARRAY:

中使用它
create type some_ty as object( s_id number );
/

create table some_tbl of some_ty;

insert into some_tbl values(1);
insert into some_tbl values(2);
insert into some_tbl values(3);

create or replace type some_arr as varray(5) of REF some_ty;
/

create type test_ty as object(
  t_id  number,
  t_list some_arr
);
/

create table test_tbl of test_ty(
  t_list CONSTRAINT test_tbl__t_list__nn NOT NULL
);

-- Collection to allow a variable length list to be passed to the insert.
CREATE TYPE INTLIST AS TABLE OF INTEGER;
/

insert into test_tbl values(
  10,
  (
    SELECT CAST( COLLECT( REF(t) ORDER BY s_id ) AS some_arr )
    FROM   some_tbl t
    WHERE  s_id MEMBER OF INTLIST( 1,2,3,4 )
    HAVING COUNT(*) = CARDINALITY( INTLIST( 1,2,3,4 ) ) -- Ensure all items are matched
  )
);

会因违反 NOT NULL 约束而抛出错误,但是:

insert into test_tbl values(
  10,
  (
    SELECT CAST( COLLECT( REF(t) ORDER BY s_id ) AS some_arr )
    FROM   some_tbl t
    WHERE  s_id MEMBER OF INTLIST( 1,2,3 )
    HAVING COUNT(*) = CARDINALITY( INTLIST( 1,2,3 ) ) -- Ensure all items are matched
  )
);

可行,然后您可以这样做:

SELECT t.t_id, DEREF( l.COLUMN_VALUE ).s_id
FROM   test_tbl t
       LEFT OUTER JOIN TABLE( t.t_list ) l
       ON ( 1 = 1 );

输出:

      T_ID              DEREF(L.COLUMN_VALUE).S_ID
---------- ---------------------------------------
        10                                       1
        10                                       2
        10                                       3