db2 用于设置完整性的子选择语句

ht4b089n  于 2022-11-07  发布在  DB2
关注(0)|答案(1)|浏览(158)

我尝试将完整性设置为大约1000个表,这些表由于挂起状态而出错。由于表太多,我无法逐个进行。子查询返回所有表的名称。以下是我使用的查询,但它现在不起作用:

SET INTEGRITY FOR TABSCHEMA.TABNAME IMMEDIATE CHECKED IN 
( SELECT TABNAME 
  FROM SYSCAT.TABLES
  WHERE ( CONST_CHECKED LIKE '%N%' AND TABSCHEMA = 'FINANCE')
  WITH ur
)

你知道吗?

ruarlubt

ruarlubt1#

这样一个庞大的SET INTEGRITY的主要问题是,如果您有一个处于check-pending状态的父子对,您必须将这两个表都包含在一个SET INTEGRITY命令中,或者先在父表上运行它,然后再用后续命令在子表上运行它。如果您只在子表上运行SET INTEGRITY,则会得到一个错误。如果相应的父表处于检查挂起状态,则将该父表从表中删除。
要将所有处于check pending状态的表拆分为不同的非相关组,以便在每个这样的表组上运行一个SET INTEGRITY,这是一项非常重要的任务。
这就是为什么最好运行如下脚本:

--#SET TERMINATOR @
SET  SERVEROUTPUT ON@

DECLARE GLOBAL TEMPORARY TABLE SESSION.BAD_TABLES 
(
  TABSCHEMA VARCHAR (128) NOT NULL
, TABNAME VARCHAR (128) NOT NULL
) WITH REPLACE ON COMMIT PRESERVE ROWS NOT LOGGED@

BEGIN
  --DECLARE L_ITER INT DEFAULT 0;
  DECLARE L_PROCESSED INT;
  DECLARE L_TABSCHEMA VARCHAR (128);
  DECLARE L_TABNAME VARCHAR (128);

  DECLARE CONTINUE HANDLER FOR SQLSTATE '23514'
  BEGIN
    INSERT INTO SESSION.BAD_TABLES (TABSCHEMA, TABNAME) VALUES (L_TABSCHEMA, L_TABNAME);
  END;

  -- Ordinal tables processing
  L1: LOOP
    --SET L_ITER = L_ITER + 1;
    --CALL DBMS_OUTPUT.PUT_LINE ('Iteration ' || L_ITER);    
    SET L_PROCESSED = 0;
    FOR V AS C1 INSENSITIVE CURSOR WITH HOLD FOR 
      SELECT 
        'SET INTEGRITY FOR "' || T.TABSCHEMA || '"."' || T.TABNAME || '" IMMEDIATE CHECKED' AS CMD
      , T.TABSCHEMA
      , T.TABNAME
      FROM SYSCAT.TABLES T
      WHERE T.TYPE = 'T' AND T.STATUS = 'C'
      AND NOT EXISTS 
      (
      SELECT 1
      FROM SYSCAT.REFERENCES R
      JOIN SYSCAT.TABLES P ON P.TABSCHEMA = R.REFTABSCHEMA AND P.TABNAME = R.REFTABNAME 
      WHERE R.TABSCHEMA = T.TABSCHEMA AND R.TABNAME = T.TABNAME 
      AND P.STATUS = 'C'
      )
      AND NOT EXISTS
      (
      SELECT 1 FROM SESSION.BAD_TABLES B WHERE B.TABSCHEMA = T.TABSCHEMA AND B.TABNAME = T.TABNAME
      )
    DO
      SET (L_TABSCHEMA, L_TABNAME) = (V.TABSCHEMA, V.TABNAME);
      EXECUTE IMMEDIATE V.CMD;
      COMMIT;
      CALL DBMS_OUTPUT.PUT_LINE (V.CMD);
      SET L_PROCESSED = L_PROCESSED + 1;
    END FOR;
    CALL DBMS_OUTPUT.PUT_LINE ('Tables processed: ' || L_PROCESSED);
    IF L_PROCESSED = 0 THEN LEAVE L1; END IF;
  END LOOP L1;

  -- MQTs processing
  SET L_PROCESSED = 0;
  FOR V AS C1 INSENSITIVE CURSOR WITH HOLD FOR 
    SELECT 
      'SET INTEGRITY FOR "' || T.TABSCHEMA || '"."' || T.TABNAME || '" IMMEDIATE CHECKED' AS CMD
    , T.TABSCHEMA
    , T.TABNAME
    FROM SYSCAT.TABLES T
    WHERE T.TYPE = 'S' AND T.STATUS = 'C'
  DO
    SET (L_TABSCHEMA, L_TABNAME) = (V.TABSCHEMA, V.TABNAME);
    EXECUTE IMMEDIATE V.CMD;
    COMMIT;
    CALL DBMS_OUTPUT.PUT_LINE (V.CMD);
    SET L_PROCESSED = L_PROCESSED + 1;
  END FOR;
  CALL DBMS_OUTPUT.PUT_LINE ('MQTs processed: ' || L_PROCESSED);

END
@

SET  SERVEROUTPUT OFF@

顺序表是迭代处理的。每次迭代处理一个表,如果它没有父表在检查挂起的时刻。
MQT随后进行处理。
如果SET INTEGRITY在会话表上失败,则将表名插入会话表中。

相关问题