我建议你有两个表:一个临时表来保持原料来自外部程序的数据和应用了业务规则的第二个表。该第二表格可以简单地是通过应用规则来查询数据的VIEW
,例如, (我正在使用CTE模拟示例数据的临时表;另外,SQL Server不具备真正的布尔类型,所以我使用CHAR(1)
列来模拟它,并且名称正在我的脑海中,所以我会将其更改为some_flag
):
WITH Staging
AS
(
SELECT *
FROM (
VALUES (0, 3750, 'T'),
(1, 5000, 'T'),
(2, 5000, 'F')
) AS T (ROW, ValueA, some_flag)
)
SELECT ROW, ValueA, some_flag,
0 AS ValueB
FROM Staging
WHERE (ValueA <= 3750 OR some_flag = 'T')
UNION
SELECT ROW, 3750 AS ValueA, some_flag,
(ValueA - 3750) AS ValueB
FROM Staging
WHERE ValueA > 3750 AND some_flag = 'F';
如果你想第二个表是基表,那么下面的限制(使用传统逻辑)似乎适用:
IF some_flag = 'F' THEN ValueA <= 3750
IF some_flag = 'T' THEN ValueB = 0
IF some_flag = 'F' AND ValueA < 3750 THEN ValueB = 0
在SQL作为CHECK
限制(我猜想一些'常识'商业规则):
CREATE TABLE MyTable
(
ROW INTEGER NOT NULL UNIQUE,
ValueA INTEGER NOT NULL CHECK (ValueA > 0),
some_flag CHAR(1) NOT NULL CHECK (some_flag IN ('T', 'F')),
ValueB INTEGER NOT NULL CHECK (ValueB >= 0),
CHECK (some_flag <> 'F' OR ValueA <= 3750),
CHECK (some_flag <> 'T' OR ValueB = 0),
CHECK (some_flag <> 'F' OR ValueA >= 3750 OR ValueB = 0)
);
然后,您可以使用上面的查询将数据从临时表复制到基表,同时不违反任何约束,但是在知道如果您的查询错误时该过程将失败!
谢谢,无法为真正的错误位提供更好的名称,它确实是一个包含T或F的char字段。感谢您的洞察力。我将其标记为我的答案,因为它包含一个示例。 – Raskaroth 2012-02-24 08:55:21