如何从立即执行语句的输出中获取结果
How to get result from output of execute immediate statement
该过程仅执行以下输出,但我试图从立即执行语句的输出中获取结果。
当前输出:
PL/SQL procedure successfully completed.
select 'PRJA' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJA.TableX UNION ALL
select 'PRJB' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJB.TableX UNION ALL
select 'PRJC' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJC.TableX UNION ALL
select 'PRJD' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJD.TableX;
我期待上面的结果 select / 输出:
SET SERVEROUTPUT ON
Declare
TYPE T IS TABLE OF MYTABLE.ID%TYPE INDEX BY PLS_INTEGER;
MYROW T;
v_sql varchar2(500);
v_sql2 varchar2(500);
v_prj_id varchar2(4000):='PRJA,PRJB,PRJC,PRJD';
BEGIN
FOR i IN (SELECT trim(regexp_substr(v_prj_id, '[^,]+', 1, LEVEL)) l
FROM dual
CONNECT BY LEVEL <= regexp_count(v_prj_id, ',') + 1
) LOOP
v_sql := v_sql || 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from '
|| i.l || '.TableX UNION ALL ' || chr(10) ;
END LOOP;
v_sql2 := RTRIM(v_sql, 'UNION ALL ' || chr(10) ) || ';';
EXECUTE IMMEDIATE v_sql2 BULK COLLECT INTO MYROW;
DBMS_OUTPUT.PUT_LINE(MYROW.XXX);
END;
/
你的变量 MYROW
是 T
类型 TABLE OF MYTABLE.ID%TYPE
所以它将只能保存一个数据类型的记录的一个值,该数据类型与数据类型相同MYTABLE.ID
.
在您的代码中,您正在获取 "PRJ_ID", EVENT, email, modified_by, modified
(5) 列并尝试将其分配给无法容纳这么多列的 MYROW
。
如果您只对 PRJ_ID
字段感兴趣,则必须从 select 子句中删除除 "PRJ_ID" 之外的所有列。
类似于:
V_SQL := V_SQL
|| 'select ''' || I.L
|| ''' AS "PRJ_ID" ' -- , EVENT, email,modified_by,modified from
|| I.L || '.TableX UNION ALL '|| CHR(10);
如果您想要所有数据,那么您需要创建可以包含适当属性的对象。请参阅此 forum 以实现对象的 table。
干杯!!
您的代码有两个明显的问题:
- 目标集合的投影与动态查询的投影不匹配。它们必须具有相同的列数(和数据类型)。
dbms_output
语句将失败,因为 MYROW 是一个集合,而 put_line()
只取标量值。
组装查询的循环也很笨拙。我们可以使用 PL/SQL 集合使它更整洁。
declare
-- record type to match projection of required output
type r is record (
prj_id varchar2(30)
, event PRJA.TableX.event%type
, email PRJA.TableX.email%type
, modified_by PRJA.TableX.modified_by%type
, modified PRJA.TableX.modified%type
);
TYPE T IS TABLE OF R;
MYROWS T; -- plural because it's a table not a record variable
v_sql varchar2(32767);
-- collection of schemas to query ...
v_prj_ids sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll('PRJA','PRJB','PRJC','PRJD');
BEGIN
FOR i IN 1 .. v_prj_ids.count() LOOP
if i > 1 then
v_sql := v_sql || chr(10) || ' UNION ALL ' || chr(10)
end if
v_sql := v_sql || 'select '''|| v_prj_ids(i) ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from '
|| v_prj_ids(i) || '.TableX ' ;
END LOOP;
EXECUTE IMMEDIATE v_sql2 BULK COLLECT INTO MYROWS;
DBMS_OUTPUT.PUT_LINE(' number of records =' || MYROWS.count());
END;
/
注意:未测试,因为我无权访问多用户环境
该过程仅执行以下输出,但我试图从立即执行语句的输出中获取结果。
当前输出:
PL/SQL procedure successfully completed.
select 'PRJA' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJA.TableX UNION ALL
select 'PRJB' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJB.TableX UNION ALL
select 'PRJC' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJC.TableX UNION ALL
select 'PRJD' AS "PRJ_ID", EVENT, email,modified_by,modified from PRJD.TableX;
我期待上面的结果 select / 输出:
SET SERVEROUTPUT ON
Declare
TYPE T IS TABLE OF MYTABLE.ID%TYPE INDEX BY PLS_INTEGER;
MYROW T;
v_sql varchar2(500);
v_sql2 varchar2(500);
v_prj_id varchar2(4000):='PRJA,PRJB,PRJC,PRJD';
BEGIN
FOR i IN (SELECT trim(regexp_substr(v_prj_id, '[^,]+', 1, LEVEL)) l
FROM dual
CONNECT BY LEVEL <= regexp_count(v_prj_id, ',') + 1
) LOOP
v_sql := v_sql || 'select '''|| i.l ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from '
|| i.l || '.TableX UNION ALL ' || chr(10) ;
END LOOP;
v_sql2 := RTRIM(v_sql, 'UNION ALL ' || chr(10) ) || ';';
EXECUTE IMMEDIATE v_sql2 BULK COLLECT INTO MYROW;
DBMS_OUTPUT.PUT_LINE(MYROW.XXX);
END;
/
你的变量 MYROW
是 T
类型 TABLE OF MYTABLE.ID%TYPE
所以它将只能保存一个数据类型的记录的一个值,该数据类型与数据类型相同MYTABLE.ID
.
在您的代码中,您正在获取 "PRJ_ID", EVENT, email, modified_by, modified
(5) 列并尝试将其分配给无法容纳这么多列的 MYROW
。
如果您只对 PRJ_ID
字段感兴趣,则必须从 select 子句中删除除 "PRJ_ID" 之外的所有列。
类似于:
V_SQL := V_SQL
|| 'select ''' || I.L
|| ''' AS "PRJ_ID" ' -- , EVENT, email,modified_by,modified from
|| I.L || '.TableX UNION ALL '|| CHR(10);
如果您想要所有数据,那么您需要创建可以包含适当属性的对象。请参阅此 forum 以实现对象的 table。
干杯!!
您的代码有两个明显的问题:
- 目标集合的投影与动态查询的投影不匹配。它们必须具有相同的列数(和数据类型)。
dbms_output
语句将失败,因为 MYROW 是一个集合,而put_line()
只取标量值。
组装查询的循环也很笨拙。我们可以使用 PL/SQL 集合使它更整洁。
declare
-- record type to match projection of required output
type r is record (
prj_id varchar2(30)
, event PRJA.TableX.event%type
, email PRJA.TableX.email%type
, modified_by PRJA.TableX.modified_by%type
, modified PRJA.TableX.modified%type
);
TYPE T IS TABLE OF R;
MYROWS T; -- plural because it's a table not a record variable
v_sql varchar2(32767);
-- collection of schemas to query ...
v_prj_ids sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll('PRJA','PRJB','PRJC','PRJD');
BEGIN
FOR i IN 1 .. v_prj_ids.count() LOOP
if i > 1 then
v_sql := v_sql || chr(10) || ' UNION ALL ' || chr(10)
end if
v_sql := v_sql || 'select '''|| v_prj_ids(i) ||''' AS "PRJ_ID", EVENT, email,modified_by,modified from '
|| v_prj_ids(i) || '.TableX ' ;
END LOOP;
EXECUTE IMMEDIATE v_sql2 BULK COLLECT INTO MYROWS;
DBMS_OUTPUT.PUT_LINE(' number of records =' || MYROWS.count());
END;
/
注意:未测试,因为我无权访问多用户环境