我在 SQL Server 2012 中遇到了这个问题,但它在 SQL Server 2017 中也很明显。
我的数据库表称为它MyTable
,包含一个不可为空的decimal(18,6)
列。new_balance
该表还包含两个整数列,它们是主键的一部分。没有其他整数字段。
存储过程有一个参数,该参数@new_balance
也定义为decimal(18,6)
. 还有 id( @id
) 和 seq_num( @seq_num
) 的参数,都定义为int
.
该过程按照以下行在表中执行插入:
INSERT INTO MyTable (id, seq_num, new_balance)
VALUES (@id, @seq_num, @new_balance);
当@new_balance
设置为 2147483647.999999 或更低时,插入按预期进行。
当@new_balance
设置为大于或等于 2147483648 的数字时,例如 2147483648.1,该过程将失败,并出现将表达式转换为 int 错误的算术溢出。我很欣赏 int 列的最大值是 2147483647。
使用以下插入也是这种情况:
INSERT INTO MyTable (id, seq_num, new_balance)
SELECT @id, @seq_num, @new_balance;
鉴于参数和表列都定义为decimal(18,6)
,我很难理解为什么将转换为 int 作为插入的一部分(尤其是在第二个语句中,我不希望有任何隐式转换)。
我还尝试将@new_balance
todecimal(18,6)
明确转换为INSERT
语句的一部分:
INSERT INTO MyTable (id, seq_num, new_balance)
SELECT @id, @seq_num, CAST(@new_balance AS decimal(18,6));
这也没有奏效。
奇怪的是,如果我在查询中指定具有相同定义的表变量并执行类似的插入,它工作正常:
DECLARE @MyTable TABLE (id int, seq_num int, new_balance decimal(18,6));
INSERT INTO @MyTable (id, seq_num, new_balance)
SELECT @id, @seq_num, @new_balance;
我在程序中尝试过这种方法,即先将记录插入@MyTable
,然后尝试插入MyTable
如下:
DECLARE @MyTable TABLE (id int, seq_num int, new_balance decimal(18,6));
INSERT INTO @MyTable (id, seq_num, new_balance) SELECT @id, @seq_num, @new_balance;
INSERT INTO MyTable (id, seq_num, new_balance) SELECT id, seq_num, new_balance FROM @MyTable;
这也不起作用。
为了完整起见,我还尝试创建值为零的记录,然后更新现有记录 - 再次失败,因此 INSERT 和 UPDATE 都会出现此问题:
INSERT INTO MyTable (id, seq_num, new_balance) SELECT @id, @seq_num, 0.00;
这很好 - 但下一步给出与上面报告的相同的错误:
UPDATE MyTable SET new_balance = @new_balance WHERE id = @id AND seq_num = @seq_num;
确认一下,表上没有INSTEAD OF INSERT
触发器或AFTER UPDATE
触发器 - 没有任何类型的触发器。
数据库上未启用更改跟踪,并且此特定字段没有约束 - 实际表中的其他十进制 (18,6) 字段有默认约束。
也没有视图添加到数据库中。
我在这个论坛上的第一个问题 - 希望有人自己经历过这个问题并且可能知道如何解决它,尽管我找不到类似性质的问题。我难住了。