我有一个货币换算应用,当您从货币和货币给它时,它会返回汇率,例如: 从美元到欧元,费率= 2.10
货币保持在MY_TABLE。
我想扩展此应用以处理转换不存在的情况。为此,我将反转计算,例如
如果从美元开始,到欧元确实不存在 返回美元,欧元,费率= 1 / 2.10。
我将创建一个自动执行此转换的视图。我是新手,我现在要求引导他们这样做。这是我的伪代码。我知道它不对,但我是在正确的轨道上吗?
CREATE OR REPLACE VIEW MY_VIEW (FROM_CURR, TO_CURR, RATE) AS
DECLARE
rates_found number;
BEGIN
select count(*)
into rates_found
from MY_TABLE
where rownum = 1
and FROM_CURR = ? and TO_CURR = ?
if rates_found = 1 then
select FROM_CURR,
TO_CURR,
RATE
from MY_TABLE
and FROM_CURR = ? and TO_CURR = ?
else
select FROM_CURR,
TO_CURR,
1 / RATE AS RATE
from MY_TABLE
and FROM_CURR = ? and TO_CURR = ?
END;
答案 0 :(得分:1)
如果您只想要一个外汇汇率查询功能,您可以尝试这样的事情:
create or replace function fx_rate
( p_from_curr my_table.from_curr%type
, p_to_curr my_table.to_curr%type )
return my_table.rate%type
deterministic
as
pragma udf;
l_rate my_table.rate%type;
begin
select min(rate) into l_rate
from my_table r
where r.from_curr = p_from_curr
and r.to_curr = p_to_curr;
if l_rate is null then
select 1/rate into l_rate
from my_table r
where r.from_curr = p_to_curr
and r.to_curr = p_from_curr;
end if;
exception
when no_data_found then
return null;
end;
min(rate)
有点减少所需的异常处理代码量,因为如果没有找到速率,它会留下l_rate
null。我假设每种货币组合实际上只保留一种外汇汇率。
pragma udf
减少了上下文切换(需要Oracle 12.1或更高版本)。
deterministic
提供缓存 - 但由于该函数不是严格确定的,因此可能会被某些人视为作弊。
(总结一下我的评论,这可能是我们可以合理地要求Oracle 将视为确定性的,即使严格来说没有真正的查找功能,所以如果是汇率在查询运行时会更新,我们明确地希望它返回旧的缓存结果而不是更新版本,这毕竟是SQL查询的功能。如果Oracle在未来实施更积极的缓存,当然会出现问题释放,或者如果不同值的数量超过隐式缓存,则无论如何都返回更新的值,因为deterministic
不做任何保证。)
result_cache
是另一种选择,但我建议测试性能,因为存在与缓存有效性检查机制等相关的一些开销,这可能会产生比执行查询更慢的最小响应时间。 result_cache
更适合占用大量资源的功能。
答案 1 :(得分:0)
正如其他人的评论所述,您无法在PLSQL
中使用view
代码。因此,您需要编写如下函数来满足您的要求。
CREATE OR REPLACE TYPE CUR_CON IS OBJECT
(
col1 VARCHAR2(100),
col2 VARCHAR2(100),
col3 number
);
CREATE OR REPLACE TYPE V_CUR_CON IS TABLE OF CUR_CON;
CREATE OR REPLACE FUNCTION MY_VIEW (FROM_CURR VARCHAR2, TO_CURR VARCHAR2, RATE NUMBER)
RETURN V_CUR_CON
AS
rates_found NUMBER;
var V_CUR_CON:=V_CUR_CON();
BEGIN
select count(*)
into rates_found
from MY_TABLE
where rownum = 1
and FROM_CURR = ? and TO_CURR = ?
if rates_found = 1 then
select CUR_CON (FROM_CURR,
TO_CURR,
RATE)
BULK COLLECT INTO var
from MY_TABLE
and FROM_CURR = ? and TO_CURR = ?
else
select CUR_CON (FROM_CURR,
TO_CURR,
1 / RATE AS RATE)
BULK COLLECT INTO var
from MY_TABLE
AND FROM_CURR = ? AND TO_CURR = ?
Return var;
END;
视图定义:因为您要创建视图。
CREATE OR REPLACE VIEW my_orig_view
as
select * from table(MY_VIEW);
选择:
Select * from my_orig_view