简体   繁体   English

在 SQL 服务器数据库表中的十进制(18,6)列中插入 2,147,483,648 或更大时,算术溢出转换为 int

[英]Arithmetic overflow converting to int when inserting 2,147,483,648 or greater into decimal(18,6) column in SQL Server database table

I am experiencing this issue in SQL Server 2012 but it is also manifest in SQL Server 2017.我在 SQL Server 2012 中遇到了这个问题,但它也出现在 SQL Server 2017 中。

My database table, call it MyTable , contains a decimal(18,6) column, new_balance , which is not nullable.我的数据库表,称为MyTable ,包含一个decimal(18,6)new_balance ,它不能为空。 The table also contains two integer columns which are part of the primary key.该表还包含两个 integer 列,它们是主键的一部分。 There are no other integer fields.没有其他 integer 字段。

A stored procedure has a parameter @new_balance which is also defined as decimal(18,6) .存储过程有一个参数@new_balance也定义为decimal(18,6) There are also parameters for id ( @id ) and seq_num ( @seq_num ), both defined as int .还有 id ( @id ) 和 seq_num ( @seq_num ) 的参数,都定义为int

The procedure carries out an insert into the table along the lines of:该过程按照以下行在表中执行插入:

INSERT INTO MyTable (id, seq_num, new_balance)
VALUES (@id, @seq_num, @new_balance);

When @new_balance is set to 2147483647.999999 or lower, the insert proceeds as expected.@new_balance设置为 2147483647.999999 或更低时,插入将按预期进行。
When @new_balance is set to a number greater than or equal to 2147483648, eg 2147483648.1, the procedure fails with an arithmetic overflow converting expression to int error.@new_balance设置为大于或等于2147483648 的数字(例如2147483648.1)时,该过程将失败并出现将表达式转换为int 错误的算术溢出。 I appreciate that the max value for an int column is 2147483647.我很欣赏 int 列的最大值是 2147483647。

This is also the case using the following insert:使用以下插入也是这种情况:

INSERT INTO MyTable (id, seq_num, new_balance)
SELECT @id, @seq_num, @new_balance;

Given that both the parameter and table column are defined as decimal(18,6) , I am struggling to see why there is a conversion to int as part of the insert (especially with the second statement where I wouldn't expect any implicit conversion).鉴于参数和表列都定义为decimal(18,6) ,我很难理解为什么将转换为 int 作为插入的一部分(尤其是第二个语句,我不希望有任何隐式转换)。

I have also tried to cast @new_balance to decimal(18,6) explicitly as part of the INSERT statement:作为INSERT语句的一部分,我还尝试将@new_balance显式转换为decimal(18,6)

INSERT INTO MyTable (id, seq_num, new_balance)
SELECT @id, @seq_num, CAST(@new_balance AS decimal(18,6));

This also didn't work.这也没有奏效。

Strangely it works fine if I specify in a query a table variable with the same definitions and carry out a similar insert:奇怪的是,如果我在查询中指定具有相同定义的表变量并执行类似的插入,它工作正常:

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;

I have tried this approach in the procedure, ie first inserting the record into @MyTable and then trying to insert into MyTable as follows:我在程序中尝试过这种方法,即首先将记录插入@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;

This didn't work either.这也不起作用。

For completeness, I also tried to create the record with a value of zero and then update the existing record - again this was unsuccessful and so this issue occurs with both an INSERT and an UPDATE:为了完整起见,我还尝试创建值为零的记录,然后更新现有记录 - 再次失败,因此 INSERT 和 UPDATE 都会出现此问题:

INSERT INTO MyTable (id, seq_num, new_balance) SELECT @id, @seq_num, 0.00;

This is fine - but the next step gives the same error as reported above:这很好 - 但下一步给出与上面报告的相同的错误:

UPDATE MyTable SET new_balance = @new_balance WHERE id = @id AND seq_num = @seq_num;

To confirm, there is no INSTEAD OF INSERT trigger or AFTER UPDATE trigger on the table - there are no triggers of any sort.确认一下,表上没有INSTEAD OF INSERT触发器或AFTER UPDATE触发器 - 没有任何类型的触发器。

Change tracking is not enabled on the database and there are no constraints for this particular field - there are default constraints on other decimal(18,6) fields that feature in the actual table.数据库上未启用更改跟踪,并且此特定字段没有约束 - 实际表中的其他十进制 (18,6) 字段有默认约束。

There have also been no views added to the database.也没有视图添加到数据库中。

My first question on this forum - hopefully someone will have experienced this themselves and may know how to resolve it although I couldn't find a question of a similar nature.我在这个论坛上的第一个问题 - 希望有人自己经历过这个问题并且可能知道如何解决它,尽管我找不到类似性质的问题。 I'm stumped.我难住了。

Having been able to insert directly into the table outside of the procedure, I looked at some of the downstream events and identified the issue:由于能够在过程之外直接插入到表中,我查看了一些下游事件并确定了问题:

After inserting the record, the system updates the status of the associated record in a parent table.插入记录后,系统会更新父表中关联记录的状态。 There is an AFTER UPDATE on this parent table which identifies this status change as requiring audit and runs a secondary procedure to create the audit history records.此父表上有一个 AFTER UPDATE 标识此状态更改为需要审计并运行辅助过程来创建审计历史记录。 As part of this capture, the system converts the old and new values in MyTable to a user-friendly format using a scalar-valued function.作为此捕获的一部分,系统使用标量值 function 将 MyTable 中的旧值和新值转换为用户友好的格式。 As part of this, the value is split into two parts to create the necessary formatting and the whole number part was being cast as an int.作为其中的一部分,该值被分成两部分以创建必要的格式,并且整数部分被转换为 int。 By changing this cast to bigint, the issue resolved itself.通过将此强制转换为 bigint,问题自行解决。

The premise of the original question was therefore wrong - the issue lay several layers down.因此,原始问题的前提是错误的——问题有好几层。

Thanks to those who contributed.感谢那些做出贡献的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将小数插入 SQL 表时出现溢出错误 - Overflow error when inserting decimal into SQL table SQL Server:将表达式转换为数据类型int的算术溢出错误 - SQL Server : Arithmetic overflow error converting expression to data type int 结果转换为十进制时,SQL Server中出现算术溢出错误 - Arithmetic overflow error in SQL Server when the result is cast to a decimal 将float转换为datetime时的算术溢出错误(SQL Server 2014) - Arithmetic overflow error when converting float to datetime (SQL Server 2014) SQL Server算术溢出错误将IDENTITY转换为数据类型int但尚未达到int的最大值 - SQL Server Arithmetic overflow error converting IDENTITY to data type int but haven't reached max of int 在where子句中限制值时,SQL算术溢出错误将varchar转换为十进制 - SQL Arithmetic Overflow error converting varchar to decimal when limiting values in where clause SQL Server 2014:将十进制(18,0)转换为十进制(18,5) - SQL Server 2014: Converting a Decimal(18,0) to a Decimal(18,5) 使用C#和SQL Server将int转换为数据类型数值的算术溢出错误 - Arithmetic overflow error converting int to data type numeric using C# and SQL Server SQL Server 2014错误:将表达式转换为数据类型int的算术溢出错误 - SQL Server 2014 error: Arithmetic overflow error converting expression to data type int 在SQL Server 2016(AWS)中将表达式转换为数据类型int的算术溢出错误 - Arithmetic overflow error converting expression to data type int in SQL Server 2016 (AWS)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM