我有以下查询,我试图在begin子句后的过程中编写。我不想将它用作游标,因为它有一些依赖性。
我想让我的数据库链接动态而不是硬编码,因此我将整个for循环放在变量中。如果我把变量拿出来,那么我的程序运行正常。我不想在尝试使dblink动态时更改我的代码的逻辑。
但这部分循环不起作用并抛出错误
在遇到以下任何一种情况时遇到文件的符号末尾:
PROCEDURE TMP_CHECK
IS
open CS for NESS_QUERY;
loop
fetch CS into REC;
exit when CS%notfound;
INSERT INTO TMP_Data(ID,NAME,ID_TST,CHK_DATE,VALUE,CHECK,SOURCE) VALUES
(IN_SEQ_NO,DB_NAME,DB_ID,REC.DAY_ID,REC.nb_ord,'ORDS','LEOSOFT');
COMMIT;
END LOOP;
CLOSE CS;
END LOOP;
END;
答案 0 :(得分:3)
动态SQL很难,因为它将编译错误转变为运行时错误。看起来你的查询有几个编译错误:重复的表别名,超出范围的别名引用,远程表之间的交叉连接(除非这是故意的,在这种情况下,你好!)。所以要做的第一件事就是让查询作为直接SQL运行,然后才能使其动态化。
也不要在模板SQL中包含注释代码。事情已经很难了,为什么要做这样的事情让他们变得更难?
ORDER BY
-- TE.market asc,
-- TE.entity asc,
TE.dayiid ASC)'
所以,现在我们已经解决了这个问题,让我们看看你正在尝试做的事情的逻辑。我们不能将PL / SQL的动态段放入程序中。这只是没有工作......
LQUERY='
FOR REC IN(
SELECT
...因为您还没有编写完整的PL / SQL语句。但是有一种方法可以做你想要的:使用游标变量。我们可以为静态和动态查询打开引用游标。 Find out more
以下仅用于说明目的:您尚未解释您的业务逻辑,因此这不一定是最佳的处理方式。但它应该解决你当前的问题:
declare
....
l_order number;
l_dayiid number;
l_ety_id number;
rc sys_refcursor;
begin
...
FOR IIS_DB IN C_DB
LOOP
IN_DB_LINK:=LEO_DB.DATABASE_LINK;
IN_DAY:=LEO_DB.DAY_ID;
open rc for
'SELECT order,dayiid,ety_id
from ...
ORDER BY TE.dayiid ASC)';
loop
fetch rc into l_order, l_dayiid, l_ety_id;
exit when rc%notfound;
...
end loop;
close rc;
" PLS-00487:对变量' REC'"
的引用无效
我认为你的问题是:
fetch CS into REC;
您已将REC定义为字符串,但显然它应该是记录类型,需要与您要提取的查询的投影相匹配。所以你需要定义这样的东西:
Type rec_t is record (
nb_ord number,
day_id number,
entity number
);
REC rec_t;
现在您可以将记录提取到REC并引用其属性。
顺便提一下,您提供给NB_ORD的nvl()
是错误的。第一个参数是你正在测试的null:500永远不会为null,这样你就可以得到每一行。你需要交换参数。