我有一组具有不同数据类型的表,我需要整合一种检索数据的方法。我认为使用函数是个好主意,但我不知道如何定义一个具有不同返回类型的函数。
例如,如何定义此函数以便能够对tabletype使用不同的定义。
CREATE OR REPLACE FUNCTION retrieve_info(field_id in integer)
RETURN pintegertypetable -- <-- how to change this to return a more generic record built dynamically in the code below?
AS
r pintegertypetable := pintegertypetable ();
BEGIN
r.extend;
r(i) := pintegertypetable (someinteger);
return r;
END;
这可能吗?有没有更好的方法来处理这个问题:最初存储在许多遗留表中的不同列,并且假设每列都有不同的数据类型,我们可以通过哪种方式检索保存原始数据类型的最新信息,而无需硬编码视图将所有内容存储在varchar2中并在客户端代码中再次投射?
答案 0 :(得分:6)
您可以通过使用弱类型的Ref Cursor作为返回类型来实现此目的。这在使用JDBC的客户端界面中特别容易实现,因为返回的游标类型可以像任何查询结果一样逐步执行,并且可以从ResultSet.getMetaData()中查询元数据。这是一个例子:
CREATE OR REPLACE PROCEDURE retrieve_info(field_id in integer, p_cursor in out sys_refcursor)
AS
BEGIN
open p_cursor for 'select * from emp';
END;
引号中的查询可以是任何类型的返回任何列的任何内容。
答案 1 :(得分:1)
使用Datajam Ltd的答案,这可能对其他人有用:
drop table xxx1;
drop table xxx2;
drop table xxx3;
drop table xxx4;
create table xxx1(val integer);
create table xxx2(val date);
create table xxx3(val number);
create table xxx4(val varchar2(100));
insert into xxx1 (val) select rownum from all_objects where rownum <= 1;
insert into xxx2 (val) select sysdate+rownum from all_objects where rownum <= 2;
insert into xxx3 (val) select 12.345+rownum from all_objects where rownum <= 3;
insert into xxx4 (val) select 'test'||rownum from all_objects where rownum <= 4;
CREATE OR REPLACE PROCEDURE retrieve_info(p_cursor in out sys_refcursor, tabname in varchar2)
AS
BEGIN
open p_cursor for 'select val from ' || tabname;
END;
/
-- CLIENT CODE IN PLSQL:
drop table logtable;
create table logtable(x varchar2(1000));
declare
v_rc sys_refcursor;
b varchar2(1000);
begin
retrieve_info(v_rc, 'xxx2'); -- here you can parameterize your call
loop
fetch v_rc into b;
exit when v_rc%notfound;
dbms_output.put_line(b);
insert into logtable(x) values(b);
end loop;
end;
/
select * from logtable;
答案 2 :(得分:1)
如果您对将单个列转换为字符串感兴趣,最简单的方法是编写具有重载函数的包。每个函数都具有相同的名称,只有输入参数的签名不同:
SQL> create or replace package str_util
2 as
3 function s (p in varchar2) return varchar2;
4 function s (p in number) return varchar2;
5 function s (p in date, fmt in varchar2 := 'dd-mon-yyyy') return varchar2;
6 end;
7 /
Package created.
SQL>
这显然是一种简单的实现。对于生产,您可能需要一些错误处理,数字格式掩码,更多数据类型等。
SQL> create or replace package body str_util
2 as
3 function s (p in varchar2) return varchar2
4 is
5 begin
6 return p;
7 end s;
8 function s (p in number) return varchar2
9 is
10 begin
11 return to_char(p);
12 end s;
13 function s (p in date, fmt in varchar2 := 'dd-mon-yyyy') return varchar2
14 is
15 begin
16 return to_char(p, fmt);
17 end s;
18 end;
19 /
Package body created.
SQL>
在foolowing查询中,我显示了表的三列的数据类型:
SQL> select dump(id) id_is_number
2 , dump(col2) col2_is_varchar
3 , dump(col3) col3_is_date
4 from big_table
5 where rownum = 1
6 /
ID_IS_NUMBER
------------------------------------------------------
COL2_IS_VARCHAR
------------------------------------------------------
COL3_IS_DATE
------------------------------------------------------
Typ=2 Len=3: 194,5,37
Typ=1 Len=11: 73,95,65,82,71,85,77,69,78,84,49
Typ=12 Len=7: 120,107,10,15,11,10,14
SQL>
在这个版本的查询中,我调用打包的函数并返回三个字符串:
SQL> select dump(str_util.s(id)) id_is_number
2 , dump(str_util.s(col2)) col2_is_varchar
3 , dump(str_util.s(col3)) col3_is_date
4 from big_table
5 where rownum = 1
6 /
ID_IS_NUMBER
------------------------------------------------------------------
COL2_IS_VARCHAR
------------------------------------------------------------------
COL3_IS_DATE
------------------------------------------------------------------
Typ=1 Len=3: 52,51,54
Typ=1 Len=11: 73,95,65,82,71,85,77,69,78,84,49
Typ=1 Len=11: 49,53,45,111,99,116,45,50,48,48,55
SQL>