programing

하위 유형 종속성을 제거하는 방법은 무엇입니까?

linuxpc 2023. 7. 5. 20:30
반응형

하위 유형 종속성을 제거하는 방법은 무엇입니까?

아래의 예에서 나는 하나를 썼습니다.to_str()함수와 하나set()에 대한 절차pls_integer아형의기능과 절차는 유형을 제외하고는 거의 동일합니다.

다른 글을 쓸 필요를 없애는 방법to_str()그리고.set()하위 유형에 의해 제공되는 제약 조건을 포기하지 않고 새로운 하위 유형의 경우?

뒤로 물러남varchar2맘에 들다

procedure set(list in varchar2, prefix in varchar2)

그리고 나서 그것을 다음과 같이 부릅니다.

set(to_str(list), 'foos:')

별로 좋은 생각은 아닌 것 같고 아직도 제공해야 할 것 같습니다.to_str()각 하위 유형에 대해

저는 Oracle 초보자이기 때문에 다양한 제안을 할 수 있습니다. Oracle의 새로운 기능은 거의 매일같이 놀랍습니다.

11.2.0.1.0을 실행하고 있습니다.

create table so1table (
  id number,
  data varchar(20)
);

create or replace package so1 as
  subtype foo_t is pls_integer range 0 .. 4 not null;
  type foolist is table of foo_t;
  procedure set(id_ in number, list in foolist default foolist(1));

  subtype bar_t is pls_integer range 5 .. 10 not null;
  type barlist is table of bar_t;
  procedure set(id_ in number, list in barlist default barlist(5));
end;
/
show errors

create or replace package body so1 as
  /* Do I have always to implement these very similar functions/procedures for
  every single type ? */
  function to_str(list in foolist) return varchar2 as
    str varchar2(32767);
  begin
    for i in list.first .. list.last loop
      str := str || ' ' || list(i);
    end loop;
    return str;
  end;

  function to_str(list in barlist) return varchar2 as
    str varchar2(32767);
  begin
    for i in list.first .. list.last loop
      str := str || ' ' || list(i);
    end loop;
    return str;
  end;

  procedure set(id_ in number, list in foolist default foolist(1)) as
    values_ constant varchar2(32767) := 'foos:' || to_str(list);
  begin
    insert into so1table (id, data) values (id_, values_);
  end;

  procedure set(id_ in number, list in barlist default barlist(5)) as
    values_ constant varchar2(32767) := 'bars:' || to_str(list);
  begin
    insert into so1table (id, data) values (id_, values_);
  end;
end;
/
show errors

begin
  so1.set(1, so1.foolist(0, 3));
  so1.set(2, so1.barlist(5, 7, 10));
end;
/

SQLPLUS> select * from so1table;

        ID DATA
---------- --------------------
         1 foos: 0 3
         2 bars: 5 7 10
create table so1table (
    id number,
    data varchar(20)
);


create or replace type parent_type as object
(
    v_number number,
    --Prefix probably belongs with a list, not an individual value.
    --For simplicity, I'm not adding another level to the objects.
    v_prefix varchar2(10)
) not instantiable not final;
/

create or replace type parentlist as table of parent_type;
/


create or replace type foo_type under parent_type
(
    constructor function foo_type(v_number number) return self as result
);
/

--The data must be stored as a NUMBER, since ADTs don't support
--PL/SQL specific data types.  The type safety is enforced by the
--conversion in the constructor.
create or replace type body foo_type is
    constructor function foo_type(v_number number) return self as result
    as
        subtype foo_subtype is pls_integer range 0 .. 4 not null;
        new_number foo_subtype := v_number;
    begin
        self.v_number := new_number;
        self.v_prefix := 'foos:';
        return;
    end;
end;
/

create or replace type foolist as table of foo_type;
/


create or replace type bar_type under parent_type
(
    constructor function bar_type(v_number number) return self as result
);
/

create or replace type body bar_type is
    constructor function bar_type(v_number number) return self as result
    as
        subtype bar_subtype is pls_integer range 5 .. 10 not null;
        new_number bar_subtype := v_number;
    begin
        self.v_number := new_number;
        self.v_prefix := 'bars:';
        return;
    end;
end;
/

create or replace type barlist as table of bar_type;
/



create or replace package so1 as
    procedure set(id_ in number, list in parentlist);
end;
/

create or replace package body so1 as

    function to_str(list in parentlist) return varchar2 as
        v_value VARCHAR2(32767);
    begin
        for i in list.first .. list.last loop
            if i = 1 then
                v_value := list(i).v_prefix;
            end if;
            v_value := v_value || ' ' || list(i).v_number;
        end loop;

        return v_value;
    end to_str;

    procedure set(id_ in number, list in parentlist) as
        values_ constant varchar2(32767) := to_str(list);
    begin
        insert into so1table (id, data) values (id_, values_);
    end set;
end so1;
/


begin
    --You probably don't want to mix foos and bars, but it is allowed. 
    so1.set(1, parentlist(foo_type(0), foo_type(3)));
    so1.set(2, parentlist(bar_type(5), bar_type(7), bar_type(10)));

    --These would generate "ORA-06502: PL/SQL: numeric or value error"
    --so1.set(1, parentlist(foo_type(5)));
    --so1.set(1, parentlist(bar_type(4)));

end;
/

select * from so1table;

이것은 당신의 질문에 답하지 않을 수도 있지만, 당신이 보여준 것처럼, 데이터를 일반 테이블에 넣고, 그것들을 연결하는 것은 어떨까요?wm_concat집계 함수?

예.,

> select * from myTable;

ID  Category  Value
--- --------- ------
1   foo       0
2   foo       3
3   bar       5
4   bar       7
5   bar       10

> select   Category||'s: '||replace(wm_concat(Value),',',' ') Data
  from     myTable
  group by Category;

Data
-------------
bars: 5 7 10
foos: 0 3

wm_concat유형에 관계없이 기능을 오버로드할 필요가 없습니다.게다가 사용할 수 있는 다른 방법들도 있습니다; 분석 기능 방법은 좋아 보이지만, 저는 테스트할 11g이 없습니다!

(편집하지 않으면 Oracle의 객체 모델, 특히 다형성을 사용하여 원하는 것을 달성할 수 있다고 생각합니다.하지만, 이건 제가 할 수 있는 일이 아닙니다...그래서 아마도 다른 누군가가 차임벨을 울릴 수 있을 것입니다.

다음 답변은 실제로 postgresql(및 plpgsql)에서 어떻게 수행할 것인지에 대한 것입니다. 또한 오라클 하위 유형에 대해서도 잘 모르지만 적어도 답변으로 이어질 수 있을 정도로 유사하다고 생각합니다.

create function add (anynonarray,anynonarray) returning anynonarray
as 'begin return $1 + $2; end';

제가 구문을 잘못했다는 것은 알지만, 어쨌든 제가 구문으로 보여주고 싶은 것을 보여줘야 합니다.

즉, "Any non-array" 또는 모든 대안을 통화 매개변수 유형으로 대체합니다.한 가지 제한 사항은 위의 예에서 "any nonarray"가 모두 동일한 유형이라는 것입니다.

그 문서는 이것을 다형성이라고 언급했습니다.

언급URL : https://stackoverflow.com/questions/6705179/how-to-eliminate-subtype-dependency

반응형