0

データベース内のすべてのテーブルの整合性を設定するスクリプト (シェル + 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 を変更する方法やシェル スクリプト / ストアド プロシージャを作成する方法を教えてください。私の最終的な目標は、チェック保留/整合性保留状態のテーブルをゼロにすることです。

助けてください。ありがとう!!

4

2 に答える 2

2

SYSCAT.REFERENCES親子の順序を確認することはできますが、依存関係のレベルが複数ある場合は、再帰クエリを作成する必要があります。2 つの相互依存テーブルがある場合 (つまり、テーブル 1 はテーブル 2 に外部キーを持ち、テーブル 2 はテーブル 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 に答える