首页 > 解决方案 > 使用循环比较 PL/SQL 表中单列的值

问题描述

之后我需要管道比较值我们如何使用循环比较PLSQL表中单列的值?之后我需要管道行比较值。记录:

type rec is record (tab_value varchar2(4000),
        trn_date date);
        V_REC REC;
        --table
        type tab is table of rec;
        V_TAB TAB;
    -- variable
    v_query(4000);
    -- defining cursor
      TYPE CUR IS REF CURSOR;
      V_CUR CUR;
    -- query
    -- MASTER TABLE
    v_query := ' SELECT D.DESCRIPTION  AS TAB_VALUE,--column on which dml performs
                        D.TRN_DATE
                      FROM TEST.TABLE D
                     WHERE 1 = 1 '||
          ' UNION
    SELECT D.DESCRIPTION AS TAB_VALUE,-- column which stores old value of master table
                    D.NEW_TRN_DATE AS TRN_DATE
                  FROM TEST.SYN_TABLE D
                 WHERE 1 = 1 ';

当对主表的描述列(D.DESCRIPTION)执行 DML 时,主表的最新值 --- 存储在历史表中

--opening cursor      
OPEN V_CUR_HIST FOR V_QUERY;
      -- loop started
      LOOP
        FETCH V_CUR 
          INTO V_REC;
        EXIT WHEN V_CUR_HIST%NOTFOUND;

        V_TAB(V_INDEX).TAB_VALUE  := V_REC.TAB_VALUE;--contains value of master & history table
        V_TAB(V_INDEX).TRN_DATE   := V_REC.TRN_DATE;
    --adding increment in v_index
        V_INDEX := V_INDEX + 1;

    END LOOP;

现在我需要的是主值和历史表值的数据比较,输出形式如下:

old_value(history table value)      new_value(master table value)
                                    a
a                                   b
b                                   c
c                                   d 

标签: oracleplsqloracle11goracle-sqldeveloper

解决方案


首先,我认为您可以在不使用 PL/SQL 的情况下做到这一点。以下查询将以常规 SQL 表示您的输出:

WITH cur_table (val, trn_date) AS
(
  SELECT 'Z', SYSDATE FROM DUAL
),
hist_table (old_val, trn_date) AS
(
  SELECT DECODE(LEVEL, 26, NULL, CHR(90-LEVEL)), SYSDATE-LEVEL
  FROM DUAL
  CONNECT BY LEVEL <= 26
)
SELECT *
FROM (SELECT sub.val AS OLD_VAL, 
             LEAD(sub.val) OVER (ORDER BY sub.trn_date) AS NEW_VAL, 
             sub.trn_date
      FROM (SELECT c.val, c.trn_date
            FROM cur_table c
            UNION ALL
            SELECT h.old_val, h.trn_date
            FROM hist_table h) sub)
WHERE new_val IS NOT NULL;

如果您确实需要使用 PL/SQL,只需调用上面的查询和BULK COLLECT INTO v_tab,您需要扩展您的记录以获取第三个值。你甚至不需要一个CURSOR. 然后我们可以遍历结果:

dbms_output.put_line('Old Value'||CHR(9)||'New Value');
IF v_tab.count > 0 THEN
  FOR i IN 1..v_tab.LAST() LOOP
    dbms_output.put_line(v_tab(i).old_value||chr(9)||v_tab(i).new_value);
  END LOOP;
END IF;

这将以您最初指定的格式输出(CHR(9) 制表符,您可能需要调整以使间距正确)。还有其他方法可以遍历集合,但我喜欢这个。您还可以使用 LOOP-EXIT WHEN NULL 设置或将 1 替换为 v_tab.FIRST()。


推荐阅读