まず、SQL * Plusを使用している場合、オブジェクトを作成してコンパイルエラーがあると通知されたら、コマンドshow errors
エラーが表示されます。
show errors
を実行した場合 、IF EXISTS
は有効な構文ではありません。あなたは
SELECT COUNT(*)
INTO l_cnt
FROM <<rest of query>>
IF( l_cnt > 0 )
THEN
RAISE_APPLICATION_ERROR ...
END IF;
ただし、コンパイルエラーを修正すると、ランタイムエラーが発生します。 surveillance
の行レベルのトリガー 、通常、surveillance
をクエリすることはできません (実行しているのがINSERT VALUES
だけの場合は可能です これは、単一の行のみを挿入することが保証されています)。これを行うと、実行時に変更トリガーエラーが発生します。
データモデルの観点から、特定の行の有効なデータが同じテーブルの他の行に格納されているデータに依存するテーブルを設計していることに気付いた場合、通常は正規化の原則に違反しているため、基礎となるデータモデル。
データモデルを保持することに本当に決心している場合は、コミット時に更新されるマテリアライズドビューを作成します。このビューには、条件に違反する行のデータのみが含まれます。次に、基準に違反した場合にコミット時にエラーをスローするマテリアライズドビューに制約を設定できます。これには、テーブルにマテリアライズドビューログが必要です。
本当にデータモデルを保持し、トリガーを使用してロジックを適用する場合は、従来の3つのトリガーソリューション(または11.2以降を使用している場合は3つの部分からなる複合トリガー)が必要になります。主キー値のコレクションを使用してパッケージを作成します。 beforeステートメントトリガーはコレクションを初期化します。行レベルのトリガーは、このコレクションに挿入および/または更新された行の主キーを挿入します。そして、afterステートメントトリガーはこのコレクションを繰り返し処理し、必要なチェックを実装します。しかし、それは多くの感動的な部分です、それが私が一般的にそれに反対する理由です。
さらに、これらすべての要素が機能していても、マルチユーザー環境ではロジックで保護されません。複数のユーザーが同時にシステムにアクセスしている場合、1人のユーザーが行を挿入し、2番目のユーザーが範囲が重複する別の行を挿入してから、各セッションがコミットされる可能性があります。その場合、両方のトリガーセットで変更が許可されますが、要件に違反するデータがテーブルに残ります。マテリアライズド・ビューは、挿入時ではなくコミット時に適用されるため、マルチユーザー環境で適切に機能します。マルチユーザー環境でトリガーを機能させる場合は、2番目のセッションのinsert
をブロックするシリアル化を強制するロジックを追加して、トリガーをさらに複雑にする必要があります。 実行から最初のセッションがコミットまたはロールバックされるまで。これにより、複雑さが増し、スケーラビリティが低下し、実装方法によっては、サポートの悪夢になる可能性があります。