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 Group by NULL 中的 SQL 返回多行