如何在 SELECT FROM 语句中使用表类型?
这个问题或多或少与这个
相同包头:
声明了以下行类型:
TYPE exch_row IS RECORD(
currency_cd VARCHAR2(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER);
这个表类型:
TYPE exch_tbl IS TABLE OF exch_row INDEX BY BINARY_INTEGER;
添加了一个变量:
exch_rt exch_tbl;
在包体中:
用一些数据填充此表变量。
在包体的过程中:
我想使用以下语句:
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
在 Oracle 中如何做到这一点?
注释
实际上,我正在 MSSQL 中寻找“表变量”解决方案:
DECLARE @exch_tbl TABLE
(
currency_cd VARCHAR(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER)
)
并在我的 StoredProcedure 中使用此表变量。
This question is more or less the same as this
In the package header :
Declared the following row type:
TYPE exch_row IS RECORD(
currency_cd VARCHAR2(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER);
And this table type:
TYPE exch_tbl IS TABLE OF exch_row INDEX BY BINARY_INTEGER;
Added a variable:
exch_rt exch_tbl;
In the package body:
Fill this table variable with some data.
In a procedure in the package body:
I want to use the following statement:
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
How to do this in Oracle ?
Notes
Actually I'm looking for the 'Table Variable' solution in MSSQL:
DECLARE @exch_tbl TABLE
(
currency_cd VARCHAR(9),
exch_rt_eur NUMBER,
exch_rt_usd NUMBER)
)
And use this Table Variable inside my StoredProcedure.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 SQL 中,您只能使用在模式级别(而不是在包或过程级别)定义的表类型,并且不能在模式级别定义索引表(关联数组)。所以 - 你必须像这样定义嵌套表
然后你可以在 SQL 中使用 TABLE 运算符来使用它,例如:
In SQL you may only use table type which is defined at schema level (not at package or procedure level), and index-by table (associative array) cannot be defined at schema level. So - you have to define nested table like this
And then you can use it in SQL with TABLE operator, for example:
在 Oracle 12C 之前,您无法从 PL/SQL 定义的表中进行选择,只能从基于 SQL 类型的表中进行选择,如下所示:
在 Oracle 12C 中,现在可以从包规范中定义的 PL/SQL 表中进行选择。
Prior to Oracle 12C you cannot select from PL/SQL-defined tables, only from tables based on SQL types like this:
In Oracle 12C it is now possible to select from PL/SQL tables that are defined in a package spec.
您无法在包内的单个查询中完成此操作 - 您无法混合 SQL 和 PL/SQL 类型,并且需要像 Tony、Marcin 和 Thio 所说的那样在 SQL 层中定义类型。
如果您确实希望在本地完成此操作,并且可以通过 VARCHAR 而不是 BINARY_INTEGER 索引表类型,则可以执行以下操作:
因此,在循环内,无论您希望使用 r0.exch_rt_eur 的任何位置,您可以使用
exch_rt(r0.currency).exch_rt_eur
,美元也同样。从匿名块进行测试:根据 Stef 发布的答案,这根本不需要在包中;使用
insert
语句可以达到相同的结果。假设EXCH
持有其他货币兑欧元的汇率,包括currency_key=1
的美元:对于价值为 19.99 英镑和 25.00 澳元的商品,您将获得
detail_items< /code>:
如果您希望货币内容更加可重用,您可以创建一个视图:
然后插入使用其中的值:
You can't do it in a single query inside the package - you can't mix the SQL and PL/SQL types, and would need to define the types in the SQL layer as Tony, Marcin and Thio have said.
If you really want this done locally, and you can index the table type by VARCHAR instead of BINARY_INTEGER, you can do something like this:
So inside your loop, wherever you would have expected to use
r0.exch_rt_eur
you instead useexch_rt(r0.currency).exch_rt_eur
, and the same for USD. Testing from an anonymous block:Based on the answer Stef posted, this doesn't need to be in a package at all; the same results could be achieved with an
insert
statement. AssumingEXCH
holds exchange rates of other currencies against the Euro, including USD withcurrency_key=1
:With items valued at 19.99 GBP and 25.00 AUD, you get
detail_items
:If you want the currency stuff to be more re-usable you could create a view:
And then insert using values from that:
感谢您对这个问题的所有帮助。我将在这里发布我的解决方案:
包头
包体
请查看。
Thanks for all help at this issue. I'll post here my solution:
Package Header
Package Body
Please review.
在包规范中,您可以执行您提到的所有操作,但不确定
INDEX BY BINARY_INTEGER;
在包正文中:
在声明中初始化表:
按顺序要将记录添加到本地集合,在 begin - end 块中您可以执行以下操作:
为了从此表中获取数据,在包体内您可以使用:
Enjoy!
PS 抱歉回复晚了:D
In package specs you can do all you mentioned but not sure about
INDEX BY BINARY_INTEGER;
In package body:
initialize the table in declarations:
in order to add record to the local collection, in begin - end block you can do:
in order to get data from this table , inside package body you can use:
enjoy!
P.S. sorry for a late answer :D