0

我正在尝试编写一个脚本(shell + DB2)来设置数据库中所有表的完整性。我使用下面的动态 SQL 生成脚本并执行它:

db2 -x "select 'SET INTEGRITY FOR '|| TABSCHEMA ||'.'||TABNAME || ' IMMEDIATE CHECKED;' from SYSCAT.TABLES where STATUS='C' and type='T'" > set_integrity.sql

它工作正常,但问题是表有关系(父子表)。它给出错误 SQL3608N“当父级处于设置完整性待定状态时无法检查子表的完整性”

请让我知道如何修改我的 SQL 或编写一个 shell 脚本/存储过程,以便它以父子顺序设置完整性。我的最终目标是使零表处于检查待处理/设置完整性待处理状态。

请帮忙。谢谢!!

4

2 回答 2

2

您当然可以查看SYSCAT.REFERENCES以确定父子顺序,但如果您有超过 1 级的依赖关系,您最终将需要编写递归查询。更不用说如果你有 2 个相互依赖的表(即 table1 在 table2 上有一个外键;而 table2 在表 1 上有一个外键),生成这个列表要困难得多。

我发现通常更容易忽略失败的SET INTEGRITY语句并重复该过程,直到没有剩余的表:

db2 -x "select 'SET INTEGRITY FOR '|| TABSCHEMA ||'.'||TABNAME || ' IMMEDIATE CHECKED;' from SYSCAT.TABLES where STATUS='C' and type='T'" > set_integrity.sql

tabcnt=$(wc -l set_integrity.sql)
while [[ ${tabcnt} -gt 0 ]] ; do
    db2 -tf set_integrity.sql

    # look for more tables in check pending state
    db2 -x "select 'SET INTEGRITY FOR '|| TABSCHEMA ||'.'||TABNAME || ' IMMEDIATE CHECKED;' from SYSCAT.TABLES where STATUS='C' and type='T'" > set_integrity.sql
    tabcnt=$(wc -l set_integrity.sql)
done

这既不漂亮也不优雅,但它确实有效。

于 2013-04-12T16:11:45.443 回答
0

你可以试试这个:

db2 << EOL
with refs (parent, child, levels) as \
      (select reftabname, tabname, 1 from syscat.references where tabschema = 'DEV' \
      union all \
      select reftabname, tabname, levels+1 \
        from refs r, syscat.references s where s.tabname = r.parent and s.tabschema = 'DEV') \
select 'set integrity for ' || st.name || ' with immediate check' \
    from (select parent, max(levels) lv from refs group by parent) rf \
      right join sysibm.systables st on rf.parent = st.name \
      where st.status = 'C' and st.type = 'T' and st.creator = 'DEV' \
      order by coalesce(rf.lv,0) desc
EOL
于 2016-05-13T03:02:06.690 回答