如何在for循环中的变量中使用DB link
How to use DB link in a variable in for loop
我有以下查询,我试图在 begin 子句之后的过程中编写这些查询。由于某些依赖性,我不想将它用作游标。
我想让我的数据库 link 动态而不是对其进行硬编码,因此我将整个 for 循环放在变量中。如果我取出变量,那么我的程序工作正常。我不想在尝试使 dblink 动态时更改我的代码逻辑。
但是这部分循环不工作并抛出错误
encounter the symbol end of the file when expecting one of the following:
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;
动态SQL很难,因为它将编译错误转化为运行时错误。看起来您的查询有几个编译错误:重复的 table 别名、超出范围的别名引用、远程 table 之间的交叉连接(除非这是故意的,在这种情况下真糟糕!)。所以要做的第一件事就是将查询 运行 直接设为 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: Invalid reference to variable '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,因此这就是您将获得的每一行。您需要交换参数。
我有以下查询,我试图在 begin 子句之后的过程中编写这些查询。由于某些依赖性,我不想将它用作游标。
我想让我的数据库 link 动态而不是对其进行硬编码,因此我将整个 for 循环放在变量中。如果我取出变量,那么我的程序工作正常。我不想在尝试使 dblink 动态时更改我的代码逻辑。
但是这部分循环不工作并抛出错误
encounter the symbol end of the file when expecting one of the following:
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;
动态SQL很难,因为它将编译错误转化为运行时错误。看起来您的查询有几个编译错误:重复的 table 别名、超出范围的别名引用、远程 table 之间的交叉连接(除非这是故意的,在这种情况下真糟糕!)。所以要做的第一件事就是将查询 运行 直接设为 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: Invalid reference to variable '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,因此这就是您将获得的每一行。您需要交换参数。