使用游标获取不同的值

Posted

技术标签:

【中文标题】使用游标获取不同的值【英文标题】:Getting distinct values using cursor 【发布时间】:2017-03-17 10:28:52 【问题描述】:

我有两个表 2017 和 2018。这两个表具有相同的列,但值不同。我想获得每列的不同值,并且我想确保 2018 年的所有唯一列都出现在 2017 年。我在每个表中有 100 多列。我已经使用游标尝试了以下查询。结果将存储在另一个名为“RESULT_MINUS”的表中

DECLARE
   COL         VARCHAR2 (200);
   OUTRECORD   VARCHAR2 (200);

   CURSOR COLUMN_NM
   IS
      SELECT COLUMN_NAME
        FROM all_tab_columns
       WHERE     table_name = 'COMPARE_2018_P1'


   CURSOR DIFFERENCE
   IS
      SELECT OUTRECORD
        FROM (SELECT DISTINCT COL
                FROM COMPARE_2018_P1
              MINUS
              SELECT DISTINCT COL
                FROM COMPARE_2017_P1);
BEGIN
   OPEN COLUMN_NM;

   LOOP
      FETCH COLUMN_NM INTO COL;

      DBMS_OUTPUT.put_line (COL);

      OPEN DIFFERENCE;

      LOOP
         FETCH DIFFERENCE INTO OUTRECORD;

         INSERT INTO RESULT_MINUS
              VALUES ('B001',
                      'COMPARE',
                      '2018',
                      COL,
                      OUTRECORD,
                      'NOT PRESENT IN 2017');
                      COMMIT;
      END LOOP;

      CLOSE DIFFERENCE;
       END LOOP;

       CLOSE COLUMN_NM;

    END;

提前谢谢..

【问题讨论】:

(1) 用您正在使用的数据库标记您的问题。 (2) 提供样本数据和期望的输出。 (3) 提出问题。例如,您当前的代码有什么问题? 为什么不同年份有不同的表? 我正在使用oracle数据库 这是 2 年的报告@jarlh 【参考方案1】:

为什么要在内循环中使用光标来插入差异?做吧:

INSERT INTO RESULT_MINUS ( . . . ) -- always include the columns
    SELECT 'B001', 'COMPARE', '2018', 'COL', COL, 'NOT PRESENT IN 2017'
    FROM (SELECT DISTINCT COL
          FROM COMPARE_2018_P1
          MINUS
          SELECT DISTINCT COL
          FROM COMPARE_2017_P1
         ) c;

至于循环遍历表中的列,这是对游标的合理使用。

您的代码不起作用,因为DIFFERENCE 光标需要在内部循环中定义。但根本不需要。

【讨论】:

但我需要比较每一列的不同值。所以我想到了使用光标 @mano 。 . .您可以将光标用于values 不需要光标。 但是当我将列传递给差异光标时,它不起作用 使用上面的查询代替差异游标。您可能需要使用动态 sql (execute immediate) 将列名放入。 我想将该查询的结果存储在另一个表中【参考方案2】:

如果要使用CURSOR 逻辑,则必须动态定义DIFFERNECEcursor(替换列名)。

改变

OPEN DIFFERENCE;

OPEN FOR
  'SELECT OUTRECORD
    FROM (SELECT DISTINCT ' || COL ||
           ' FROM COMPARE_2018_P1
          MINUS
          SELECT DISTINCT ' || COL ||
           ' FROM COMPARE_2017_P1)'; 

并删除光标的定义。

当然,由于性能更好,使用来自其他答案的动态插入的方法更受欢迎。

【讨论】:

以上是关于使用游标获取不同的值的主要内容,如果未能解决你的问题,请参考以下文章

BULK 收集和 FORALL 两次插入数据

Oracle 选择变量,错误 ORA-00947 没有足够的值

使用一个引用游标处理两个不同的查询

在 UDF 中使用游标,返回具有不同表名称的列

MYSQL 游标学习及使用实例

如何使用 JS 获取不同的值并在 JSON 上求和