基本金額に応じた価格を含むテーブルがあります。例として、基準額が 100 以下の場合、価格は 10 ですが、基準額が 100 より大きく 1000 以下の場合、価格は 20 であり、最終的に基準額が 100 より大きい場合は、 1000 の場合、価格は 30 です。このテーブルの単純化されたバージョンは次のようになります。
PRICE_CODE START_RANGE END_RANGE PRICE_AMOUNT
100 0,00 100,00 10,00
100 100,01 1000,00 20,00
100 1000,01 99999999,99 30,00
110 0,00 99999999,99 15,00
列レベルのチェック制約を使用すると、各レコードに有効な範囲情報が含まれていることを簡単に確認できます。問題は、次の例のように、各価格コードの範囲情報にオーバーラップやギャップが含まれていないことを確認するために、ある種のテーブル レベルのチェック制約も必要であることです。
PRICE_CODE START_RANGE END_RANGE PRICE_AMOUNT
100 0,00 200,00 10,00
100 100,01 1000,00 20,00
100 1100,01 99999999,99 30,00
動作している検証手順を作成しましたが、データベース内に検証ロジックを呼び出す場所が見つからないという問題があります。当然、レコード レベルのトリガーを配置することはできませんが、ステートメント レベルのトリガーは、個別の挿入、更新、および削除を行うことができ、最終結果に対してのみ範囲を検証する必要がある場合には機能しません。検証ロジックは次のようになります。
SELECT * FROM (
SELECT price_code, start_range, end_range, price_amount
, lag (end_range) OVER (PARTITION BY price_code ORDER BY end_range) prev_end
, lead (start_range) OVER (PARTITION BY price_code ORDER BY start_range) next_start
FROM my_test
ORDER BY price_code, start_range, end_range)
WHERE start_range <= prev_end
OR end_range >= next_start
OR (next_start - end_range) > 0.01
OR (start_range - prev_end) > 0.01
1 つの方法はもちろん、データ アクセス レイヤーに検証ロジックを配置することですが、それでも SQL を直接使用して検証を回避することができます。私が興味を持っているのは、この種の「テーブルレベルの制約」をデータベースに実装して、誰も無効な範囲データをコミットできないようにする方法について誰かがアイデアを持っているかどうかです。私たちは主に Oracle を使用しているので、Oracle ベースのソリューションに興味がありますが、他の RDBMS がこの問題をどのように解決したかにも興味があります。