避免TSQL数据转换错误
我认为最好用一个简单的例子来说明这一点。下面的SQL块会导致“DB库错误:20049严重性:4消息:数据转换导致溢出”消息,但这是怎么回事避免TSQL数据转换错误,tsql,sybase,data-conversion,Tsql,Sybase,Data Conversion,我认为最好用一个简单的例子来说明这一点。下面的SQL块会导致“DB库错误:20049严重性:4消息:数据转换导致溢出”消息,但这是怎么回事 declare @a numeric(18,6), @b numeric(18,6), @c numeric(18,6) select @a = 1.000000, @b = 1.000000, @c = 1.000000 select @a/(@b/@c) go 这与: select 1.000000/(1.000000/1.000000) go 哪
declare @a numeric(18,6), @b numeric(18,6), @c numeric(18,6)
select @a = 1.000000, @b = 1.000000, @c = 1.000000
select @a/(@b/@c)
go
这与:
select 1.000000/(1.000000/1.000000)
go
哪种方法可以很好地工作?这只是猜测,但是否DBMS不会查看变量的动态值,而只查看潜在值?因此,一个六进制数字除以一个六进制数字可能得到一个十二进制数字;在文字部分,DBMS知道没有溢出。但仍然不确定DBMS为什么会在意——它是否应该返回两个六位小数的结果,最多返回一个18位小数?因为您在第一个示例中声明了变量,结果应该是相同的声明(即数字(18,6)),但事实并非如此
我不得不说,第一个在SQL2005中工作(返回1.000000[相同声明的类型]),而第二个返回(1.00000000000000000000000[完全不同的声明])。我上次尝试使用Sybase时遇到了相同的问题(很多年前)。出于SQL Server的心态,我没有意识到Sybase会试图强制输出小数——从数学上讲,这是它应该做的事情 从: 发生算术溢出错误时 新类型的小数点太少 用于容纳结果的位置 再往下看: 在隐式转换为数字的过程中 或十进制类型,比例损失 生成缩放误差。使用 arithabort数值_截断选项 确定这种错误的严重程度 被考虑在内。默认设置, arithabort数值_截断, 中止导致错误的语句 错误,但继续处理其他错误 交易中的报表或 一批。如果你设置了arithabort 数字截断关闭,自适应 服务器截断查询结果并 继续处理 因此,假设在您的场景中精度损失是可以接受的,您可能希望在事务开始时执行以下操作:
SET ARITHABORT NUMERIC_TRUNCATION OFF
SET ARITHABORT NUMERIC_TRUNCATION ON
然后在交易结束时:
SET ARITHABORT NUMERIC_TRUNCATION OFF
SET ARITHABORT NUMERIC_TRUNCATION ON
这就是多年前为我解决的问题 不直接相关,但使用Sybase ASE(12.5.0.3)可能会因算术溢出错误而节省一些时间 我在一个临时表中设置了一些默认值,我打算稍后更新该表,但无意中发现了一个算术溢出错误
declare @a numeric(6,3)
select 0.000 as thenumber into #test --indirect declare
select @a = ( select thenumber + 100 from #test )
update #test set thenumber = @a
select * from #test
显示错误:
Arithmetic overflow during implicit conversion of NUMERIC value '100.000' to a NUMERIC field .
在我的头脑中,这应该是可行的,但不可行,因为没有声明“thenumber”列(或间接声明为decimal(4,3))。因此,您必须间接地将temp表列按比例和精度声明为所需的格式,就像我的例子中的000.000一样
select 000.000 as thenumber into #test --this solved it
希望这能节省一些时间:)我不知道这是否增加了什么,但select(@a*@b)/@c在代数上是相同的,它会发生什么情况。