你不能做一個單一的查詢中包 - 你不能混用SQL和PL/SQL類型,並且需要像Tony,Marcin和Thio所說的那樣在SQL層中定義類型。
如果你真的想這個在本地完成的,你可以指數VARCHAR代替BINARY_INTEGER表類型,你可以做這樣的事情:
-- dummy ITEM table as we don't know what the real ones looks like
create table item(
item_num number,
currency varchar2(9)
)
/
insert into item values(1,'GBP');
insert into item values(2,'AUD');
insert into item values(3,'GBP');
insert into item values(4,'AUD');
insert into item values(5,'CDN');
create package so_5165580 as
type exch_row is record(
exch_rt_eur number,
exch_rt_usd number);
type exch_tbl is table of exch_row index by varchar2(9);
exch_rt exch_tbl;
procedure show_items;
end so_5165580;
/
create package body so_5165580 as
procedure populate_rates is
rate exch_row;
begin
rate.exch_rt_eur := 0.614394;
rate.exch_rt_usd := 0.8494;
exch_rt('GBP') := rate;
rate.exch_rt_eur := 0.9817;
rate.exch_rt_usd := 1.3572;
exch_rt('AUD') := rate;
end;
procedure show_items is
cursor c0 is
select i.*
from item i;
begin
for r0 in c0 loop
if exch_rt.exists(r0.currency) then
dbms_output.put_line('Item ' || r0.item_num
|| ' Currency ' || r0.currency
|| ' EUR ' || exch_rt(r0.currency).exch_rt_eur
|| ' USD ' || exch_rt(r0.currency).exch_rt_usd);
else
dbms_output.put_line('Item ' || r0.item_num
|| ' Currency ' || r0.currency
|| ' ** no rates defined **');
end if;
end loop;
end;
begin
populate_rates;
end so_5165580;
/
所以你的循環,只要你會預期到內使用r0.exch_rt_eur
您改爲使用exch_rt(r0.currency).exch_rt_eur
,而USD則相同。從一個匿名塊測試:
begin
so_5165580.show_items;
end;
/
Item 1 Currency GBP EUR .614394 USD .8494
Item 2 Currency AUD EUR .9817 USD 1.3572
Item 3 Currency GBP EUR .614394 USD .8494
Item 4 Currency AUD EUR .9817 USD 1.3572
Item 5 Currency CDN ** no rates defined **
基於答案燕姿發佈,這並不需要在一個包在所有; insert
聲明可以實現相同的結果。假設EXCH
保存與currency_key=1
對歐元等貨幣,包括美元的匯率:
insert into detail_items
with rt as (select c.currency_cd as currency_cd,
e.exch_rt as exch_rt_eur,
(e.exch_rt/usd.exch_rt) as exch_rt_usd
from exch e,
currency c,
(select exch_rt from exch where currency_key = 1) usd
where c.currency_key = e.currency_key)
select i.doc,
i.doc_currency,
i.net_value,
i.net_value/rt.exch_rt_usd AS net_value_in_usd,
i.net_value/rt.exch_rt_eur as net_value_in_euro
from item i
join rt on i.doc_currency = rt.currency_cd;
隨着項目價值19.99英鎊和25.00澳元,你detail_items
:
DOC DOC_CURRENCY NET_VALUE NET_VALUE_IN_USD NET_VALUE_IN_EURO
--- ------------ ----------------- ----------------- -----------------
1 GBP 19.99 32.53611 23.53426
2 AUD 25 25.46041 18.41621
如果你要使用的貨幣東西要更可重複使用,你可以創建一個視圖:
create view rt as
select c.currency_cd as currency_cd,
e.exch_rt as exch_rt_eur,
(e.exch_rt/usd.exch_rt) as exch_rt_usd
from exch e,
currency c,
(select exch_rt from exch where currency_key = 1) usd
where c.currency_key = e.currency_key;
然後插入使用值在:
insert into detail_items
select i.doc,
i.doc_currency,
i.net_value,
i.net_value/rt.exch_rt_usd AS net_value_in_usd,
i.net_value/rt.exch_rt_eur as net_value_in_euro
from item i
join rt on i.doc_currency = rt.currency_cd;
正如其他人所說,你不能用包中聲明的類型來做到這一點。目前尚不清楚爲什麼你要這樣做,而不是使用真正的表來保存匯率,或者你想要對選定的數據做什麼。這是在遊標?你真的在尋找你選擇的特定貨幣的數據嗎?您是否根據匯率操縱項目價值?更多的上下文可能有助於激發替代方法。 – 2011-03-02 11:48:58