Oracle 动态 SQL 多行返回

Posted

技术标签:

【中文标题】Oracle 动态 SQL 多行返回【英文标题】:Oracle Dynamic SQL Multiple Row Return 【发布时间】:2018-02-08 03:59:54 【问题描述】:

没有太多使用 Oracle 的经验,甚至不确定这是否可以做到。我正在尝试创建动态 SQL 并执行它,有问题的 SQL 导致返回多行,每行有 3 列。我能够很好地创建 SQL 语句,它是我坚持的执行部分。我正在使用来自 here 的示例,但出现此错误:

Error report -
ORA-00942: table or view does not exist
ORA-06512: at line 41
00942. 00000 -  "table or view does not exist"

从此代码:

DECLARE thecount number;
 thesql varchar2(8000);
 suffix VARCHAR2(20);
 finalsql varchar2(8000);
 TYPE results IS TABLE OF EDW_HPM.DYNAMIC_TEMP%ROWTYPE;
 results_tbl results;

  CURSOR c1 is
       select cast(cast(substr(p.TABLE_SUFFIX,2,20) as Number(19))as varchar2(50))  
         from support.data_set_phys p
        where p.name not like '%UPD' and p.name like 'FY%' and p.name like '%Encounters'
        and p.is_active = 1 and p.owner_id in ('001441631324','000001666805')
        and NAME not like '%TEST%' and NAME not like 'old%' and NAME not like '%new%' and
        NAME not like '%NEW%' and name not like '%BACK%' and name not like '%back%'
        and cast(replace(substr(p.name, 1, 4),'FY', '20')as int) between 2018 and
        2018 union
                  select cast(cast(substr(p.TABLE_SUFFIX,2,20) as Number(19))as varchar2(50))
         from support.data_set_phys p
        where p.name not like '%UPD' and p.name like 'EPIC HB %' and p.name like '%Encounters'
        and p.is_active = 1 and p.owner_id in ('001441631324','000001666805')
        and NAME not like '%TEST%' and NAME not like 'old%' and NAME not like '%new%' and
        NAME not like '%NEW%' and name not like '%BACK%' and name not like '%back%'
        and cast(replace(substr(p.name, 9, 4),'FY', '20')as int) between 2018 and
      2018;

BEGIN

   OPEN c1;
   LOOP
      FETCH c1 INTO suffix;
      EXIT WHEN c1%NOTFOUND;
    thesql := thesql ||'SELECT facility_id,patient_type_id ,count(pat_account_no) FROM encounter_' ||suffix|| ' e group by facility_id, patient_type_id union ';
   END LOOP;
   CLOSE c1;

   finalsql :=SUBSTR(thesql,1,length(thesql)-7);

   EXECUTE IMMEDIATE finalsql BULK COLLECT INTO results_tbl; 


END allrows_by;

此行触发的错误:

 EXECUTE IMMEDIATE finalsql BULK COLLECT INTO results_tbl;

我可以向您保证表 EDW_HPM.DYNAMIC_TEMP 确实存在,这一定是某种语法错误,或者我正在尝试一些在 Oracle 中不可能的事情。任何帮助将不胜感激。

【问题讨论】:

错误信息很明显。您的架构中没有这样的表encounter_<suffix> @KaushikNayak 实际上,如果表存在但执行 PL/SQL 的架构无权访问它,也会收到错误消息。 您可以使用 dbms_output.put_line 输出 finalsql 变量值,然后复制并运行查询(finalsql 值)并识别不存在的表 【参考方案1】:

您的代码比您链接到的示例要复杂得多。不仅驱动查询极其复杂,而且您的动态语句是与生成的表名的联合。

“这一定是某种语法错误,或者我正在尝试一些在 Oracle 中不可能发生的事情。”

动态 SQL 很难,因为它将编译错误转化为运行时错误。

“我可以向您保证,表 EDW_HPM.DYNAMIC_TEMP 确实存在”

在这种情况下,可能是 生成的表名 正在抛出 ORA-00942。

这很容易调试:而不是执行语句显示它。

dbms_output.put_line(finalsql);

现在您可以通过在 SQL 客户端中运行该语句来验证该语句,如果您不能立即发现灯笼裤。

可能的原因

表名格式错误 生成的 SQL 为不存在的表组合名称 生成的名称引用了不同模式中的表,并且没有同义词 生成的名称引用不同架构中的表,有同义词,但您的用户对表没有权限。

【讨论】:

原来是这样:生成的 SQL 为不存在的表组合名称。

以上是关于Oracle 动态 SQL 多行返回的主要内容,如果未能解决你的问题,请参考以下文章

Oracle - 匿名过程循环遍历多个表(动态) - 查询返回多行

Oracle SQL插入多行并返回一些东西

Oracle Group by NULL 中的 SQL 返回多行

oracle执行动态sql选择脚本并返回表格数据

oracle 存储过程执行动态SQL 返回结果给游标,外部程序获得dataset结果集。

从 Oracle 函数返回多个值