![](/img/trans.png)
[英]Oracle Pass multiple rows or resultset of a SQL to a function as parameter
[英]Pass type as parameter to Oracle function
我正在嘗試在 Oracle 中編寫一個可以接受類型作為參數的函數。
我環顧四周,但找不到任何示例,所以我想知道是否有可能。
這是我想要實現的簡化版本:
create function a_function
( text_in in varchar2, type_in in type ) -- can this be done?
return type_in
is
val_out type_in;
begin
val_out := cast(text_in as type_in);
return val_out;
end;
然后上面應該被稱為:
a_function('2021-01-20', date)
a_function('111', number)
像許多其他編程語言一樣,您可以重載函數。 但是,您必須將它們放入 PACKAGE 中。 它不能作為獨立功能工作。 會是這樣:
CREATE OR REPLACE PACKAGE a_functions AS
FUNCTION a_function (val_in IN NUMBER)
RETURN NUMBER;
FUNCTION a_function (val_in IN DATE)
RETURN NUMBER;
FUNCTION a_function (val_in IN VARCHAR2)
RETURN NUMBER;
END a_functions;
CREATE OR REPLACE PACKAGE BODY a_functions AS
FUNCTION a_function (val_in IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN 1;
END;
FUNCTION a_function (val_in IN DATE)
RETURN NUMBER IS
BEGIN
RETURN 1;
END;
FUNCTION a_function (val_in IN VARCHAR2)
RETURN NUMBER is
begin
return 3;
end;
END a_functions;
正確調用它們,例如使用a_functions.a_function(123)
或a_functions.a_function(SYSDATE)
或a_functions.a_function(DATE '2020-01-20')
我能想到的最通用的方法是使用 anydata 類型。
因此,您需要的功能將與此類似
create or replace function let_us_use_anydata(p_any_data in anydata, p_data_type in varchar2) return anydata
is
l_varchar varchar2(1000);
l_number number;
l_date date;
res anydata;
begin
if p_data_type = 'SYS.NUMBER' then
l_number := anydata.AccessNumber(p_any_data);
l_number := l_number + 1000; -- do any number stuff
res := anydata.ConvertNumber(l_number); -- put it back to the output
elsif p_data_type = 'SYS.VARCHAR2' then
l_varchar := anydata.AccessVarchar2(p_any_data);
l_varchar := l_varchar || ' Hi there!'; -- do anything you can do with a string
res := anydata.ConvertVarchar2(l_varchar);
elsif p_data_type = 'SYS.DATE' then
l_date := anydata.AccessDate(p_any_data);
l_date := l_date - 1; -- any date operations
res := anydata.ConvertDate(l_date);
end if;
return res;
end;
使用這個功能就像
聲明虛擬的任何數據;
procedure any_data_output(p_anydata anydata)
is
begin
case anydata.GetTypeName(dummy)
when 'SYS.VARCHAR2' then
dbms_output.put_line('VARCHAR2: ' || anydata.AccessVarchar2(dummy));
when 'SYS.NUMBER' then
dbms_output.put_line('NUMBER: ' || anydata.AccessNumber(dummy));
when 'SYS.DATE' then
dbms_output.put_line('DATE: ' || to_char(anydata.AccessDate(dummy), 'dd.mm.yyyy hh24:mi:ss'));
end case;
end;
begin
dummy := let_us_use_anydata(anydata.ConvertNumber(12), 'SYS.NUMBER');
any_data_output(dummy);
dummy := let_us_use_anydata(anydata.ConvertVarchar2('Hello.'), 'SYS.VARCHAR2');
any_data_output(dummy);
dummy := let_us_use_anydata(anydata.ConvertDate(sysdate), 'SYS.DATE');
any_data_output(dummy);
end;
所以輸出是
NUMBER: 1012
VARCHAR2: Hello. Hi there!
DATE: 21.01.2020 08:37:50
請注意,匿名塊中有一個使用 anydata 的過程。 這是為了顯示您還可以動態檢測數據類型,而無需在單獨的參數中指定它。
你可以使用任何你希望的數據類型,我只是選擇了這三個,因為它們是最受歡迎的。
無論如何,這是一個非常有趣的案例。 謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.