Масштаб потерь при обновлении таблицы с числовыми типами умножения или деления в SQL server 2008 R2
У меня есть приложение, которое пользователь определяет формулу на основе других столбцов(например, c=(a-b)*100/a), а затем приложение создает запрос обновления SQL для вычисления результата (типы всех столбцов числовые). Когда формула содержит умножение и деление, результат не является точным. Я знаю, что SQL Server усекает масштаб, чтобы соответствовать результату умножения и деления.
http://stackoverflow.com/questions/1056323/difference-between-numeric-float-and-decimal-in-sql-server
https://blogs.msdn.microsoft.com/sqlprogrammability/2006/03/29/multiplication-and-division-with-numerics/
Но я путаюсь с нижеприведенным тестом. Когда я использую переменную или использовать формулу в запрос SELECT результат точный, но когда я использую формулу в запрос Update в результате неточной!
<pre lang="SQL">--USE NUMERIC CREATE TABLE TblTest ( a [numeric](18, 8) NULL, b [numeric](28, 15) NULL, c [numeric](28, 15) NULL ) ON [PRIMARY] INSERT TblTest (a, b) VALUES (158.62700000, 155.000000000000000) UPDATE TBlTest SET c = (a - b) * 100 / a SELECT a, b, c, (a-b) * 100 / a AS c2 FROM TBlTest --Result: c=2.286495000000000 !!! and c2=2.286495993746 DECLARE @a AS NUMERIC(18, 8) = 158.62700000 DECLARE @b AS NUMERIC(28, 15) = 155.000000000000000 DECLARE @c AS NUMERIC(28, 15) SELECT (@a - @b) * 100 / @a --Result: 2.286495993746 SELECT @c = (@a - @b) * 100 / @a --Result: 2.286495993746000 --USE FLOAT CREATE TABLE TblTest2 ( a FLOAT(53) NULL, b FLOAT(53) NULL, c FLOAT(53) NULL ) ON [PRIMARY] INSERT TblTest2 (a, b) VALUES (158.62700000, 155.000000000000000) UPDATE TBlTest2 SET c = (a - b) * 100 / a SELECT a, b, c, (a - b) * 100 / a AS c2 FROM TBlTest2 --Result: 2.28649599374634
Что я уже пробовал:
Я тестирую функцию CLR для числовых типов деления, и результат был удовлетворительным, но она не подходит для моего приложения.
Tomas Takac
Умножение и деление с числовым / десятичным числом может быть сложным из-за масштаба и точности выравнивания. У меня нет времени, чтобы дать вам правильный ответ прямо сейчас, но то, что вы можете попробовать, это преобразовать в FLOAT сделать calc, а затем преобразовать обратно в numeric.