2015-01-26 39 views
0

我想了解SQL Server 2008 R2中CHECK約束的失敗(SQL Server 2012上發生同樣的問題)。CHECK在雙精度列上SUM失敗的約束條件

我的sql命令只是更新了兩列的數量126.3,並且約束檢查兩列的總和是否與第三列相匹配。

下面是重現該問題的步驟:

CREATE TABLE FailedCheck (item VARCHAR(10), qty_total DOUBLE PRECISION, qty_type1 DOUBLE PRECISION, qty_type2 DOUBLE PRECISION) 
ALTER TABLE FailedCheck ADD CONSTRAINT TotalSum CHECK(qty_total = (qty_type1 + qty_type2)); 
INSERT INTO FailedCheck VALUES ('Item 2', 101.66, 91.44, 10.22); 
UPDATE FailedCheck SET qty_total = qty_total + 126.3, qty_type1 = qty_type1 + 126.3 

柱qty_total必須包含的總和(qty_type1和qty_type2)。所有列都是'雙精度'。如果我將值從126.3更改爲126,它可以工作,我已經測試了其他值(int和double),並且無法理解爲什麼有時它有效,有時不會。

我的CHECK約束有什麼問題?

PS:對不起,我的英語,這不是我的主要語言。

+2

爲什麼'qty_total'只是一個計算列(爲什麼不是'DECIMAL'具有固定的精度,因爲[這是'FLOAT' /'DOUBLE'發生的事情](http:// classicasp。 aspfaq.com/general/why-does-3-2-1-5-4-7000000000000002.html))?這就像擁有多餘的數據 - 生日的表單字段,然後是你年齡段的不同字段,然後在他們不匹配時抱怨。由於您始終可以從出生日期計算年齡,因此要求提供年齡也沒有多大意義(不必介意存儲並維護它)。 – 2015-01-26 20:56:32

+1

那麼'DOUBLE PRECISION'是一個近似的數據類型,你應該使用這種檢查約束的精確數據類型 – Lamak 2015-01-26 20:56:49

+0

你也可以看到更多信息[在這個線程中](http://stackoverflow.com/questions/1056323 /差之間數字浮子和 - 十進制在-SQL服務器)。 – 2015-01-26 21:04:53

回答

3

您決定使用只包含近似值的浮點數據類型 - 非常精確,但只能達到一定程度。 1.3很可能被存儲爲1.299999999999998或者其他東西。所以近似值91.44和10.22的總和可能恰好是101.66的近似值,但也可能會有很小的差異。

切勿將浮點值與等號(=)進行比較。

最好不要使用浮點類型,如果不是真的,真的需要。改爲使用DECIMAL。

+0

是的,讓我們阻止不需要的近似數字數據類型。 – 2015-01-26 21:10:19