将列名从一个游标传递到另一个游标的 select 语句
Passing column name from one cursor to select statement of another cursor
我有两个游标 c11 和 c2。我有两个 tables compare1 和 compare2.Both 具有相同的列但值不同。我想将 c1 的结果传递给 c2 游标。我正在从 user_tab_columns 中获取 table 的列名称。我想传递列名以获取比较 1 和比较 2 tables 之间唯一记录的差异。但是 c1 中的列名没有传递给 c2.Please 找到我试过的代码。
DECLARE
COL VARCHAR2 (200);
OUTRECORD VARCHAR2 (200);
CURSOR c1 IS
SELECT COLUMN_NAME
FROM all_tab_columns
WHERE table_name = 'COMPARE1';
CURSOR c2( col varchar(200)) IS--col is the column names from c1
(SELECT DISTINCT COL
FROM COMPARE1
MINUS
SELECT DISTINCT COL
FROM COMPARE2);
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO COL;
DBMS_OUTPUT.put_line (COL);
OPEN c2(col);--col Is not passing to 2nd cursor
LOOP
FETCH c2 INTO OUTRECORD;--outrecord is empty is col is not passed to 2nd cursor
INSERT INTO RESULT
VALUES ('B001',
'COMPARE',
'2018',
COL,
OUTRECORD,--empy value
'NOT PRESENT IN 2017');
COMMIT;
END LOOP;
CLOSE c2;
END LOOP;
CLOSE c1;
END;
帮我提前传值给c1.Thanks
您的代码未按预期运行的主要原因是您将第一个游标的列名称作为文字值传递到第二个游标。
因此,当您在第二个游标中执行减号操作时,您是在比较一个字符串是否与该字符串相同,这意味着不会返回任何行。 IE。它本质上是:
select 'x' from some_table
minus
select 'x' from some_other_table;
要解决这个问题,您需要使用动态 sql - 下面是一个使用游标和引用游标的示例:
DECLARE
rc SYS_REFCURSOR;
outrecord VARCHAR2(200);
BEGIN
FOR r1 IN (SELECT column_name col
FROM all_tab_columns
WHERE table_name = 'COMPARE1')
LOOP
dbms_output.put_line(r1.col);
OPEN rc FOR 'SELECT '||r1.col||' col'||CHR(10)||
'FROM compare1'||CHR(10)||
'MINUS'||CHR(10)||
'SELECT '||r1.col||' col'||CHR(10)||
'FROM compare2';
LOOP
FETCH rc
INTO outrecord;
EXIT WHEN rc%NOTFOUND;
INSERT INTO RESULT -- you should list the columns being inserted into here
VALUES
('B001',
'COMPARE',
'2018',
r1.col,
outrecord,
'NOT PRESENT IN 2017');
COMMIT;
END LOOP;
END LOOP;
CLOSE rc;
END;
/
您可以看到我已经将围绕第一个游标的循环转换为游标循环,而不是显式获取每一行。这样,您就不必担心检查是否已到达行尾或关闭游标。通过我在缺少的 exit when rc%notfound
子句中添加的第二个游标的内部循环。
另请注意,我已从您的减号查询中删除了 distinct
s - minus
已经区分了行,因此无需明确说明。
但是,您要做的是逐行插入,这根本不是最佳方法 - 您应该在单个插入语句中完成所有工作,您可以看到下面:
BEGIN
FOR r1 IN (SELECT column_name col
FROM all_tab_columns
WHERE table_name = 'COMPARE1')
LOOP
dbms_output.put_line(r1.col);
execute immediate 'INSERT INTO RESULT'||CHR(10)|| -- you should list the columns being inserted into here
'SELECT ''B001'','||CHR(10)||
' ''COMPARE'','||CHR(10)||
' ''2018'','||CHR(10)||
' '''||r1.col||''','||CHR(10)||
' '||r1.col||CHR(10)||
'FROM compare1'||CHR(10)||
'MINUS'||CHR(10)||
'SELECT ''B001'','||CHR(10)||
' ''COMPARE'','||CHR(10)||
' ''2018'','||CHR(10)||
' '''||r1.col||''','||CHR(10)||
' '||r1.col||CHR(10)||
'FROM compare2';
END LOOP; END;
/
N.B。未经测试。
我有两个游标 c11 和 c2。我有两个 tables compare1 和 compare2.Both 具有相同的列但值不同。我想将 c1 的结果传递给 c2 游标。我正在从 user_tab_columns 中获取 table 的列名称。我想传递列名以获取比较 1 和比较 2 tables 之间唯一记录的差异。但是 c1 中的列名没有传递给 c2.Please 找到我试过的代码。
DECLARE
COL VARCHAR2 (200);
OUTRECORD VARCHAR2 (200);
CURSOR c1 IS
SELECT COLUMN_NAME
FROM all_tab_columns
WHERE table_name = 'COMPARE1';
CURSOR c2( col varchar(200)) IS--col is the column names from c1
(SELECT DISTINCT COL
FROM COMPARE1
MINUS
SELECT DISTINCT COL
FROM COMPARE2);
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO COL;
DBMS_OUTPUT.put_line (COL);
OPEN c2(col);--col Is not passing to 2nd cursor
LOOP
FETCH c2 INTO OUTRECORD;--outrecord is empty is col is not passed to 2nd cursor
INSERT INTO RESULT
VALUES ('B001',
'COMPARE',
'2018',
COL,
OUTRECORD,--empy value
'NOT PRESENT IN 2017');
COMMIT;
END LOOP;
CLOSE c2;
END LOOP;
CLOSE c1;
END;
帮我提前传值给c1.Thanks
您的代码未按预期运行的主要原因是您将第一个游标的列名称作为文字值传递到第二个游标。
因此,当您在第二个游标中执行减号操作时,您是在比较一个字符串是否与该字符串相同,这意味着不会返回任何行。 IE。它本质上是:
select 'x' from some_table
minus
select 'x' from some_other_table;
要解决这个问题,您需要使用动态 sql - 下面是一个使用游标和引用游标的示例:
DECLARE
rc SYS_REFCURSOR;
outrecord VARCHAR2(200);
BEGIN
FOR r1 IN (SELECT column_name col
FROM all_tab_columns
WHERE table_name = 'COMPARE1')
LOOP
dbms_output.put_line(r1.col);
OPEN rc FOR 'SELECT '||r1.col||' col'||CHR(10)||
'FROM compare1'||CHR(10)||
'MINUS'||CHR(10)||
'SELECT '||r1.col||' col'||CHR(10)||
'FROM compare2';
LOOP
FETCH rc
INTO outrecord;
EXIT WHEN rc%NOTFOUND;
INSERT INTO RESULT -- you should list the columns being inserted into here
VALUES
('B001',
'COMPARE',
'2018',
r1.col,
outrecord,
'NOT PRESENT IN 2017');
COMMIT;
END LOOP;
END LOOP;
CLOSE rc;
END;
/
您可以看到我已经将围绕第一个游标的循环转换为游标循环,而不是显式获取每一行。这样,您就不必担心检查是否已到达行尾或关闭游标。通过我在缺少的 exit when rc%notfound
子句中添加的第二个游标的内部循环。
另请注意,我已从您的减号查询中删除了 distinct
s - minus
已经区分了行,因此无需明确说明。
但是,您要做的是逐行插入,这根本不是最佳方法 - 您应该在单个插入语句中完成所有工作,您可以看到下面:
BEGIN
FOR r1 IN (SELECT column_name col
FROM all_tab_columns
WHERE table_name = 'COMPARE1')
LOOP
dbms_output.put_line(r1.col);
execute immediate 'INSERT INTO RESULT'||CHR(10)|| -- you should list the columns being inserted into here
'SELECT ''B001'','||CHR(10)||
' ''COMPARE'','||CHR(10)||
' ''2018'','||CHR(10)||
' '''||r1.col||''','||CHR(10)||
' '||r1.col||CHR(10)||
'FROM compare1'||CHR(10)||
'MINUS'||CHR(10)||
'SELECT ''B001'','||CHR(10)||
' ''COMPARE'','||CHR(10)||
' ''2018'','||CHR(10)||
' '''||r1.col||''','||CHR(10)||
' '||r1.col||CHR(10)||
'FROM compare2';
END LOOP; END;
/
N.B。未经测试。