|
On 11-Feb-2016 15:50 -0600, Justin Taylor wrote:
I'm trying to figure out how SQL arithmetic involving decimals is
giving an integer result. I've put together a sample query that
replicates my question.
with Values as
( select cast(1.5267 as decimal(31,4)) as A
, cast(1.6 as decimal(12,4)) as B
from SYSIBM.SYSDUMMY1
)
select Values.*
, (A - B) / B * 100.00 as RESULT
from Values;
This gives: 1.5267 1.6 0
The RESULT column has a type of decimal(31,2), but the value is
zero. With a precision of 2, RESULT should actually be -4.58.
The above discussion was already /answered/ and the OP resolved their issue, but seems nobody mentioned the ability to override the method SQL uses to decide what precision will be used to perform intermediate calculations of numeric expression.
The default rules [best I can recall, long referred-to in the lab as the /precision reduction/ rules] for determining the precision for the operators, would have effected a reduction in the scale [portion of the precision] being maintained for the intermediate results of the full numeric expression; the division portion of the expression effected a loss of all precision to the right of the decimal point [the scale], thus effectively producing an integer result of zero [for which multiplication by any constant is still zero].
There is a simple and oft acceptable means to prevent the loss of precision in the intermediate calculation; i.e. set the Minimum Divide Scale to greater than the default of zero. AFaIK there is still no capability via Start Interactive SQL (STRSQL), but both the Run SQL Statement (RUNSQLSTM) script processor and the Run SQL (RUNSQL) single-statement processor have a Decimal Result Options (DECRESULT) parameter, with the third element being the Minimum Divide Scale defined as "The minimum divide scale (number of decimal positions to the right of the decimal point) that should be returned for both intermediate and result data types" for which the command parameter element defaults to zero. At least some of the SQL pre-compiler commands were updated to have that same parameter added; e.g. Create SQL ILE RPG Object (CRTSQLRPGI).
For the command invocations; e.g. the following specification would have enable achieving the expected result in the given example:
DECRESULT(*n, *n, 4)
Note: See also the "Maximum Precision" and "Maximum scale" settings in the command parameter DECRESULT(), the first and second elements, respectively. JDBC and ODBC should also have equivalent capabilities for achieving such modified settings.
For SQL program sources, the SET OPTION statement; e.g. the following specification would have enable achieving the expected result in the given example:
SET OPTION DECRESULT = (31, 31, 4) ;
[http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/db2/rbafzsoption.htm]
"...
.-,-------------------------------------.
V |
>>-SET OPTION---+-ALWBLK = --alwblk-option------------+-+--><
+-ALWCPYDTA = --alwcpydta-option------+
...
+-DECRESULT = --decresult-option------+
...
...
decresult-option
.-31-----------.
|-(-+-max-precision+-+--------------------------------------------+-)-|
| .-31--------. |
'-,-+-max-scale-+-+------------------------+-'
| .-0----------------. |
'-,-+-min-divide-scale-+-'
..."
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.