하위 유형 종속성을 제거하는 방법은 무엇입니까?
아래의 예에서 나는 하나를 썼습니다.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
'programing' 카테고리의 다른 글
데이터베이스에서 테이블의 마지막 업데이트/삽입/삭제를 찾는 실용적인 방법은 무엇입니까? (0) | 2023.07.05 |
---|---|
로컬 및 원격 Git 저장소를 1커밋만큼 롤백하는 중 (0) | 2023.07.05 |
ESLint: TypeError: this.libOptions.parse가 함수가 아닙니다. (0) | 2023.07.05 |
구체적인 클래스 이름을 문자열로 얻는 방법은 무엇입니까? (0) | 2023.07.05 |
MongoDB Shell - 이름에 마침표가 있는 액세스 컬렉션? (0) | 2023.07.05 |