设置完整性的子选择语句
Posted
技术标签:
【中文标题】设置完整性的子选择语句【英文标题】:Subselect statement to set integrity 【发布时间】:2021-10-31 20:38:17 【问题描述】:我正在尝试将完整性设置为大约 1000 个由于挂起状态而出错的表。我不能一张一张地去,因为桌子太多了。子查询返回所有表的名称。这是我使用的查询,现在不工作:
SET INTEGRITY FOR TABSCHEMA.TABNAME IMMEDIATE CHECKED IN
( SELECT TABNAME
FROM SYSCAT.TABLES
WHERE ( CONST_CHECKED LIKE '%N%' AND TABSCHEMA = 'FINANCE')
WITH ur
)
有什么想法吗?
【问题讨论】:
要么在脚本(任何脚本语言)中执行此操作,要么在 SQL 例程或 SQL 匿名块中执行此操作。您需要两个单独的步骤。第一步生成 SQL 语句(每个表一个)。第二步依次执行这些语句。 是的,我对查询不太擅长,所以我不知道该怎么做你所描述的……但是谢谢……有什么解决方案可以像上面的脚本一样运行吗? 【参考方案1】:如此庞大的SET INTEGRITY
s 的主要问题是,如果您有一对处于待检查状态的父子对,您必须将两个表都包含在一个 SET INTEGRITY
命令中,或者运行它首先是父表,然后在子表上使用后续命令。如果您只在子表上运行SET INTEGRITY
,并且相应的父表处于检查挂起状态,则会出现错误。
将所有待检查的表拆分为不同的非相对组以在每个这样的表组上运行单个 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
失败,则表名被插入到会话表中。
【讨论】:
非常感谢,我会尽力回复您以上是关于设置完整性的子选择语句的主要内容,如果未能解决你的问题,请参考以下文章