引用数组值

时间:2017-04-09 12:09:20

标签: sql oracle user-defined-types

我遇到了以下问题。

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循环执行此操作。我只是想知道是否有一种简单的方法。

2 个答案:

答案 0 :(得分:1)

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

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> 
  

"示例学生和班级。一节课最多可以有10名学生。并且有许多表我不能这样做。"

嗯,你可以这样做:

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
);

答案 1 :(得分:0)

如果您使用Object-Relational database并想要引用其他对象,请使用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