我有以下查询,其中accc_no的数据类型是varchar,wthdrl_amt是money,sav_amt是money,trxn_id是bigint。
DECLARE @acc_no NVARCHAR(MAX) = N''
DECLARE @symbol NVARCHAR(MAX) = N''
DECLARE @loop int = 0
DECLARE @loop2 int = 0
SELECT @symbol += N'' + acc_no + ',' FROM sav_transaction GROUP BY acc_no HAVING (SUM(sav_amt)<SUM(wthdrl_amt))
IF LEN(@symbol) > 1
BEGIN
WHILE @loop < LEN(@symbol)
BEGIN
SET @loop2 = CHARINDEX(',', @symbol ,@loop)
SET @acc_no = SUBSTRING(@symbol, @loop, @loop2-@loop)
UPDATE sav_transaction
SET wthdrl_amt = wthdrl_amt-(SELECT ABS(SUM(sav_amt) - SUM(wthdrl_amt))
FROM sav_transaction WHERE acc_no = @acc_no)
WHERE acc_no = @acc_no AND trxn_id = (SELECT MAX(trxn_id) FROM sav_transaction WHERE acc_no = @acc_no )
END
SET @loop = @loop2 +1
END
但是当我跑这个时,我得到错误:
Msg 8115, Level 16, State 2, Line 15
Arithmetic overflow error converting expression to data type money.
The statement has been terminated.
我使用了具有相同数据类型的字段。但是找不到错误。
答案 0 :(得分:1)
要查看差异,我们可以查看文档:
money的文档:
Data type Range Storage
money -922,337,203,685,477.5808 to 922,337,203,685,477.5807 8 bytes
smallmoney -214,748.3648 to 214,748.3647 4 bytes
money和smallmoney数据类型精确到它们所代表的货币单位的万分之一。
与decimal比较:
使用最大精度时,有效值为-10 ^ 38 + 1到10 ^ 38 - 1。
Precision Storage
1 - 9 5 bytes
10 - 19 9 bytes
20 - 28 13 bytes
29 - 38 17 bytes
所以他们并不完全相同,只是相似。 DECIMAL(19,4)的范围略大于MONEY(它可以存储-10 ^ 15 + 0.0001到10 ^ 15 - 0.0001),但还需要一个存储字节。
换句话说,这有效:
CREATE TABLE Table1 (test DECIMAL(19,4) NOT NULL);
INSERT INTO Table1 (test) VALUES
(999999999999999.9999);
SELECT * FROM Table1
999999999999999.9999
但这不是:
CREATE TABLE Table1 (test MONEY NOT NULL);
INSERT INTO Table1 (test) VALUES
(999999999999999.9999);
SELECT * FROM Table1
Arithmetic overflow error converting numeric to data type money.
还有语义差异。如果你想存储货币价值,那么使用类型货币是有意义的。
答案 1 :(得分:0)
更改此部分SELECT @symbol + = N''+ CAST(acc_no AS nvarchar(MAX))+因为acc_no不是nvarchar并且在添加操作期间优先,并尝试将N''和其他添加项转换为其类型< / p>
DECLARE @acc_no NVARCHAR(MAX) = N''
DECLARE @symbol NVARCHAR(MAX) = N''
DECLARE @loop int = 0
DECLARE @loop2 int = 0
SELECT @symbol += N'' + CAST(acc_no AS nvarchar(MAX)) + ',' FROM sav_transaction GROUP BY acc_no HAVING (SUM(sav_amt)<SUM(wthdrl_amt))
IF LEN(@symbol) > 1
BEGIN
WHILE @loop < LEN(@symbol)
BEGIN
SET @loop2 = CHARINDEX(',', @symbol ,@loop)
SET @acc_no = SUBSTRING(@symbol, @loop, @loop2-@loop)
UPDATE sav_transaction SET
wthdrl_amt = wthdrl_amt-(SELECT SUM(sav_amt) - SUM(wthdrl_amt) FROM sav_transaction WHERE acc_no = @acc_no)
WHERE acc_no = @acc_no AND trxn_id = (SELECT MAX(trxn_id) FROM sav_transaction WHERE acc_no = @acc_no )
END
SET @loop = @loop2 +1
END