我们有一个表格,其中包含取决于基本金额的价格。例如,如果基础金额小于或等于 100,则价格为 10,但如果基础金额大于 100 但小于或等于 1000,则价格为 20,最后如果基础金额大于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
一种方法当然是将验证逻辑放在数据访问层,但仍然可以通过直接使用 SQL 来绕过验证。我感兴趣的是,是否有人对如何在数据库中实现这种“表级约束”有一些想法,以确保没有人能够提交无效的范围数据。我们正在使用 Oracle,所以我对基于 Oracle 的解决方案很感兴趣,但我也对任何其他 RDBMS 如何解决这个问题感兴趣。