且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 BIGINT 的 TSQL 算术溢出

更新时间:2023-11-10 16:11:52

当您进行这样的计算时,各个数字的存储大小刚好足以容纳该数字,即: numeric(1,0).看看这个:

When you're doing calculations like this, the individual numbers are stored just large enough to hold that number, ie: numeric(1,0). Check this out:

注意
当您使用 +、-、*、/, 或 % 算术运算符执行隐式或显式int、smallint、tinyint 的转换,或 bigint 常量值浮点数、实数、十进制或数字数据类型,SQL Server 的规则在计算数据时适用表达式的类型和精度结果不同取决于是否查询是否自动参数化.

Caution
When you use the +, -, *, /, or % arithmetic operators to perform implicit or explicit conversion of int, smallint, tinyint, or bigint constant values to the float, real, decimal or numeric data types, the rules that SQL Server applies when it calculates the data type and precision of the expression results differ depending on whether the query is autoparameterized or not.

因此,类似的表达在查询有时会产生不同的结果.当查询不是自动参数化,常数值首先转换为数字,其精度刚好足以容纳常量的值,之前转换为指定的数据类型.例如,常数值 1 是转换为数字 (1, 0),然后常数值 250 转换为数字 (3, 0).

Therefore, similar expressions in queries can sometimes produce different results. When a query is not autoparameterized, the constant value is first converted to numeric, whose precision is just large enough to hold the value of the constant, before converting to the specified data type. For example, the constant value 1 is converted to numeric (1, 0), and the constant value 250 is converted to numeric (3, 0).

当查询被自动参数化时,常量值总是被转换为转换为之前的数字 (10, 0)最后的数据类型.当...的时候/运营商参与,不仅可以结果类型的精度因人而异类似的查询,但结果值也可以不同.例如,自动参数化的结果值包含表达式的查询SELECT CAST (1.0/7 AS float) 将与结果值不同相同的查询不是自动参数化,因为结果自动参数化查询的将是截断以适应数字 (10,0) 数据类型.想要查询更多的信息关于参数化查询,请参阅简单的参数化.

When a query is autoparameterized, the constant value is always converted to numeric (10, 0) before converting to the final data type. When the / operator is involved, not only can the result type's precision differ among similar queries, but the result value can differ also. For example, the result value of an autoparameterized query that includes the expression SELECT CAST (1.0 / 7 AS float) will differ from the result value of the same query that is not autoparameterized, because the results of the autoparameterized query will be truncated to fit into the numeric (10, 0) data type. For more information about parameterized queries, see Simple Parameterization.

http://msdn.microsoft.com/en-us/library/ms187745.aspx

这不是 SQL Server 中的错误.在同一页面上,它指出:

This isn't a bug in SQL Server. From that same page, it states:

int 数据类型是 SQL Server 中的主要整数数据类型.

The int data type is the primary integer data type in SQL Server.

SQL Server 不会自动将其他整数数据类型(tinyint、smallint 和 int)提升为 bigint.

SQL Server does not automatically promote other integer data types (tinyint, smallint, and int) to bigint.

这是定义的行为.作为程序员,如果您有理由相信您的数据会溢出数据类型,则需要采取预防措施来避免这种情况.在这种情况下,只需将这些数字之一转换为 BIGINT 即可解决问题.

This is defined behavior. As a programmer, if you have reason to believe that your data will overflow the data type, you need to take precautions to avoid that situation. In this case, simply converting one of those numbers to a BIGINT will solve the problem.

DECLARE @a BIGINT
SET @a = 7*11*13*17*19*23*29*CONVERT(BIGINT, 31)