Ste*_*ath 13 oracle select row
这个问题或多或少与此相同
在包头中:
声明以下行类型:
TYPE exch_row IS RECORD(
currency_cd VARCHAR2(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER);
Run Code Online (Sandbox Code Playgroud)
而这个表类型:
TYPE exch_tbl IS TABLE OF exch_row INDEX BY BINARY_INTEGER;
Run Code Online (Sandbox Code Playgroud)
添加了一个变量:
exch_rt exch_tbl;
Run Code Online (Sandbox Code Playgroud)
在包体中:
用一些数据填充此表变量.
在包体中的过程中:
我想使用以下语句:
CURSOR c0 IS
SELECT i.*, rt.exch_rt_eur, rt.exch_rt_usd
FROM item i, exch_rt rt
WHERE i.currency = rt.exchange_cd
Run Code Online (Sandbox Code Playgroud)
如何在Oracle中执行此操作?
笔记
实际上我正在寻找MSSQL中的"表变量"解决方案:
DECLARE @exch_tbl TABLE
(
currency_cd VARCHAR(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER)
)
Run Code Online (Sandbox Code Playgroud)
并在我的StoredProcedure中使用此表变量.
Mar*_*ski 17
在SQL中,您只能使用在模式级别定义的表类型(不在包或过程级别),并且无法在模式级别定义索引表(关联数组).所以 - 你必须像这样定义嵌套表
create type exch_row as object (
currency_cd VARCHAR2(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER);
create type exch_tbl as table of exch_row;
Run Code Online (Sandbox Code Playgroud)
然后你可以在带有TABLE运算符的SQL中使用它,例如:
declare
l_row exch_row;
exch_rt exch_tbl;
begin
l_row := exch_row('PLN', 100, 100);
exch_rt := exch_tbl(l_row);
for r in (select i.*
from item i, TABLE(exch_rt) rt
where i.currency = rt.currency_cd) loop
-- your code here
end loop;
end;
/
Run Code Online (Sandbox Code Playgroud)
Ton*_*ews 14
在Oracle 12C之前,您无法从PL/SQL定义的表中进行选择,只能从基于SQL类型的表中进行选择,如下所示:
CREATE OR REPLACE TYPE exch_row AS OBJECT(
currency_cd VARCHAR2(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER);
CREATE OR REPLACE TYPE exch_tbl AS TABLE OF exch_row;
Run Code Online (Sandbox Code Playgroud)
在Oracle 12C中,现在可以从包规范中定义的PL/SQL表中进行选择.
您无法在包内的单个查询中执行此操作-您无法混合使用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;
/
Run Code Online (Sandbox Code Playgroud)
因此,在循环中,无论您希望在哪里使用它,都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 **
Run Code Online (Sandbox Code Playgroud)
根据Stef发布的答案,根本不需要将其包装在包装中。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;
Run Code Online (Sandbox Code Playgroud)
使用价值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
Run Code Online (Sandbox Code Playgroud)
如果您希望货币的东西更可重用,则可以创建一个视图:
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;
Run Code Online (Sandbox Code Playgroud)
然后使用其中的值插入:
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;
Run Code Online (Sandbox Code Playgroud)