SQLServer decimal insert into bigint column失去精度但没有抛出错误

SQLServer decimal insert into bigint column loses precision but no error thrown

下面的代码演示了使用标准插入语句将具有精度的十进制值插入到 bigint 列中。 SqlServer 会截断精度但不会抛出错误来通知 DBA。

CREATE TABLE [dbo].[TableX]
(
    [ColumnA] [bigint] NULL
);

SET NUMERIC_ROUNDABORT ON;
SET XACT_ABORT ON;

insert into [dbo].[TableX] (ColumnA)
select 999999999.99;

select * from [dbo].[TableX] 
-- output ==> 999999999 (precision missing) -- no error thrown?

问题:

我。您能解释一下为什么会丢失精度并且不会抛出任何错误吗?

二.在这种情况下,您能否建议一种强制 SQLServer 抛出错误的方法?

注: SQL 当尝试将 decimal 转换为 bigint 时,批量插入会在精度丢失时引发错误,因此我相当确定必须有一种方法可以根据示例代码使用标准插入语句来实现此目的。

第一个问题的答案是设计使然:https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql

这意味着对于您的第二个问题,您需要添加一些逻辑来检查十进制值并按照您需要的方式处理它们。


关于批量插入的最后一点 - 我对此不是 100%,所以很乐意接受建议 - 我相信这是因为 SQL 服务器不知道你的平面文件中的数据类型是什么,所以一切都是一个字符串。然后您可以声明它应该转换为 dateint 并且 SQL 将尝试转换。

从字符串到 decimalint 数据类型的转换要严格得多,这就是为什么 bulk insert 会抛出错误,如下所示:

declare @t table([ColumnA] decimal(12,2) NULL);

SET NUMERIC_ROUNDABORT ON;
SET XACT_ABORT ON;

insert into @t(ColumnA)
select '9999.99';

select * from @t
-- output ==> 9999.99 -- no error thrown

go

declare @t table([ColumnA] [bigint] NULL);

SET NUMERIC_ROUNDABORT ON;
SET XACT_ABORT ON;

insert into @t(ColumnA)
select '9999.99';

select * from @t
-- output ==> error thrown