立即执行结果到表类型
Posted
技术标签:
【中文标题】立即执行结果到表类型【英文标题】:EXECUTE IMMEDIATE results into Table Type 【发布时间】:2019-10-23 12:49:48 【问题描述】:我需要让 EXECUTE IMMEDIATE 将其结果返回到表类型(AS TABLE OF)
如果立即执行返回单个值,我可以使用“INTO somevariable”保存结果
但是,我的立即执行将返回一个多列的表,并且没有多少谷歌搜索可以帮助我弄清楚!
首先我创建类型
CREATE OR REPLACE TYPE T_VALIDITY_RECORD AS OBJECT (
TIME_COL DATE,
VALUE_COL NUMBER
);
/
CREATE OR REPLACE TYPE T_VALIDITY_TABLE AS TABLE OF T_VALIDITY_RECORD;
/
然后我尝试代码
DECLARE
RET_TABLE T_VALIDITY_TABLE;
BEGIN
EXECUTE IMMEDIATE 'SELECT my_date,
my_numbers
FROM my_table
WHERE somthing = somthingelse' INTO RET_TABLE;
END;
这只是一个非常简化的例子,真正的代码会做(会做其他事情)
我尝试了各种方法,例如 BULK COLLECT INTO 等,但似乎无法正常工作。
我收到以下错误:
错误报告 ORA-00932:不一致的数据类型:预期 - 得到 - ORA-06512:在第 5 行 00932. 00000 - “不一致的数据类型:预期的 %s 得到了 %s” *原因: *行动:
【问题讨论】:
【参考方案1】:您需要BULK COLLECT INTO
,并且需要收集T_VALIDITY_OBJECT
的实例,而不是NUMBER
和DATE
值对。
Oracle 设置:
CREATE OR REPLACE TYPE T_VALIDITY_RECORD AS OBJECT (
VALUE_COL NUMBER,
TIME_COL DATE
);
/
CREATE OR REPLACE TYPE T_VALIDITY_TABLE AS TABLE OF T_VALIDITY_RECORD;
/
CREATE TABLE my_table ( my_date, my_number, something ) AS
SELECT 1, DATE '2019-01-01', 1 FROM DUAL UNION ALL
SELECT 2, DATE '2019-01-02', 1 FROM DUAL UNION ALL
SELECT 3, DATE '2019-01-03', 1 FROM DUAL;
PL/SQL:
DECLARE
RET_TABLE T_VALIDITY_TABLE;
BEGIN
EXECUTE IMMEDIATE 'SELECT T_VALIDITY_RECORD( my_date, my_number )
FROM my_table
WHERE something = :value'
BULK COLLECT INTO RET_TABLE
USING 1;
FOR i IN 1 .. RET_TABLE.COUNT LOOP
DBMS_OUTPUT.PUT_LINE( i || ': ' || ret_table(i).time_col || ', ' || ret_table(i).value_col );
END LOOP;
END;
/
输出:
1: 2019-01-01 00:00:00, 1 2: 2019-01-02 00:00:00, 2 3: 2019-01-03 00:00:00, 3
db小提琴here
【讨论】:
【参考方案2】:一些问题:
您将两列提取到一个结构中,该结构只有一个元素,由两个值组成。
另外,如果您的选择可以提供多于一行,则需要BULK COLLECT
。
如果您在这里不需要严格的动态 sql,则可以使用纯 SQL 查询:
DECLARE
RET_TABLE T_VALIDITY_TABLE;
BEGIN
SELECT T_VALIDITY_RECORD(my_date, my_numbers )
bulk collect INTO RET_TABLE
FROM my_table ;
END;
如果因为其他原因需要动态sql:
DECLARE
RET_TABLE T_VALIDITY_TABLE;
BEGIN
execute immediate ' SELECT T_VALIDITY_RECORD(my_date,
my_numbers )
FROM my_table'
bulk collect INTO RET_TABLE;
END;
【讨论】:
谢谢,但我上面的例子被简化了,我需要使用立即执行(因为我正在动态创建 SQL 部分)有没有办法使用立即执行来实现?以上是关于立即执行结果到表类型的主要内容,如果未能解决你的问题,请参考以下文章
从给定数据库中选择所有表时,如何将 [dbo] 前缀附加到表名?