如何消除子类型依赖?
在下面的示例中,我为每个 pls_integer
子类型编写了一个 to_str()
函数和一个 set()
过程。除了类型之外,功能和过程几乎相同。
如何消除为新子类型编写另一个 to_str()
和 set()
的需要,而不放弃子类型提供的约束?
回到 varchar2
like
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
In the example below I have written one to_str()
function and one set()
procedure for every pls_integer
subtype. The functions and procedures are almost identical except the type.
How I can eliminate the need to write yet another to_str()
and set()
for a new subtype without giving up the constraint provided by the subtype ?
Falling back to varchar2
like
procedure set(list in varchar2, prefix in varchar2)
and then calling it as
set(to_str(list), 'foos:')
doesn't sound too great idea and I still need to provide to_str()
for each subtype.
I'm open for all kind of different proposals as I'm Oracle newbie and new Oracle features suprise me almost daily.
I'm running 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这可能无法回答您的问题,但为什么不将数据放入常规表中,然后使用
wm_concat
聚合函数将它们连接起来,如您所示?即,
wm_concat
与类型无关,因此无需重载函数。此外,还有其他方法可以使用;解析函数法看起来不错,但是我没有11g来测试!(编辑否则,我认为您可以使用 Oracle 的对象模型实现您正在寻找的目标;特别是多态性。但是,这超出了我的范围......所以也许其他人可以帮腔。)
This might not answer your question, but why not put the data in a regular table, then concatenate them, as you show, using the
wm_concat
aggregation function?i.e.,
wm_concat
is type independent, so there's no need for you to overload your functions. Moreover, there are other methods that can be used; the analytical function method looks good, but I don't have 11g to test with!(Edit Otherwise, I think you can achieve what you are looking for using Oracle's object model; specifically polymorphism. However, this is beyond me...so maybe someone else can chime in.)
下面的答案实际上是关于你如何在 postgresql (和 plpgsql)中做到这一点,我也不知道 oracle 子类型,但我认为它们足够相似,至少它会引导你找到你的答案。
我知道我搞砸了语法,但无论如何它应该显示我想用它显示的内容。
我们的想法是,它将替代“anynonarray”或任何替代方案 与调用参数的类型。一个限制是上例中的所有“anynonarray”都属于同一类型。
该文档将此称为多态性。
The following answer is actually to how you'd do it in postgresql (and plpgsql), and I also do not know about oracle subtypes, but I assume they are similar enough that at the very least it will lead you to your answer.
I know I botched the syntax, but it should show what I want to show with it, anyway.
The idea is that it will substitute "anynonarray" or any of the alternatives with the type of the parameter of the call. One restriction is that all the "anynonarray" in the example above will be of the same type.
The documentation referred to this as polymorphism.