DB2 DESCRIBEの使い方 結論:小数部を計算し小数部の桁数を決め、実数部の桁数が決まる

テーブル定義の表示

 db2 => DESCRIBE TABLE SAKAGUCHI.TEST
                                Data type                     Column
Column name                     schema    Data type name      Length     Scale Nulls
------------------------------- --------- ------------------- ---------- ----- ------
AMOUNT                       SYSIBM    DECIMAL                     20     0 Yes
NUM                             SYSIBM    INTEGER                      4      0 Yes
NAME                            SYSIBM    VARCHAR                    10     0 Yes
  3 record(s) selected.

入力データは、

db2 => SELECT AMOUNT,NUM FROM SAKAGUCHI.TEST;

AMOUNT            NUM
----------------- -----------
 12345678901234567890.           3

  1 record(s) selected.

overflowのexception:

db2 => SELECT (1.0/3)*AMOUNT FROM SAKAGUCHI.TEST;

1
---------------------------------
SQL0802N  Arithmetic overflow or other arithmetic exception occurred.
SQLSTATE=22003
ひとつの領域の計算途中でOverflowするから?

db2 => SELECT AMOUNT - 1.00/3 FROM SAKAGUCHI.TEST;

1
---------------------------------
SQL0413N  Overflow occurred during numeric data type conversion.
SQLSTATE=22003
AMOUNT:decimal(20,0)を1.00/3:decimal(31,30)に合わせるため?

サイズの確認


db2 => DESCRIBE SELECT (1.0/3) FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 484   DECIMAL               31,30  1                                         1

db2 => DESCRIBE SELECT (1.0/3)*AMOUNT FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,30  1                                         1

db2 => DESCRIBE SELECT AMOUNT*(1.0/3) FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,30  1                                         1

db2 => DESCRIBE SELECT AMOUNT - 1.00/3 FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,30  1                                         1

計算結果がDECIMAL(31,30)となり、それにAMOUNTの20桁の数値を代入するのでOverflowが発生する。

解決策

以下のように明示的に20桁の整数部が入るように型を指定する。
db2 => SELECT CAST(1.0/3 AS DECIMAL(31,11))*AMOUNT FROM SAKAGUCHI.TEST;

1
---------------------------------
  4115226300370370366.99588477370

  1 record(s) selected.

db2 => DESCRIBE SELECT CAST(1.0/3 AS DECIMAL(31,11))*AMOUNT FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,11  1                                         1

参考までに割り切れても結果は同じである。

db2 => DESCRIBE SELECT 1.0/2 FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 484   DECIMAL               31,30  1                                         1

足し算でも同じ。

db2 => DESCRIBE SELECT AMOUNT + 1.00/3 FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,30  1                                         1

引き算でも

db2 => DESCRIBE SELECT AMOUNT - 1.00/3 FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,30  1                                         1

数値の掛け算でも精度が下がる

db2 => DESCRIBE SELECT AMOUNT *(12 / CAST(13 AS DECIMAL(20,5) ) ) FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,15  1                                         1

db2 => DESCRIBE SELECT AMOUNT * CAST( 12 / 13 AS DECIMAL(20,5) ) FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31, 5  1                                         1

db2 => SELECT AMOUNT *(12 / CAST(13 AS DECIMAL(20,5) ) ) FROM SAKAGUCHI.TEST;

1
---------------------------------
SQL0802N  Arithmetic overflow or other arithmetic exception occurred.
SQLSTATE=22003

解決策

db2 => DESCRIBE SELECT AMOUNT *(CAST(12 AS DECIMAL(20,5)) / CAST(13 AS DECIMAL(20,5) ) ) FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31,11  1                                         1

db2 => DESCRIBE SELECT AMOUNT * CAST(12/13 AS DECIMAL(20,5)) FROM SAKAGUCHI.TEST;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 485   DECIMAL               31, 5  1                                         1

db2 => SELECT AMOUNT *(CAST(12 AS DECIMAL(20,5)) / CAST(13 AS DECIMAL(20,5) ) ) FROM SAKAGUCHI.TEST;

1
---------------------------------
 11396011293361823352.22222222230

  1 record(s) selected.

結論:小数部を計算し小数部の桁数を決め、実数部の桁数が決まる。

db2 => SELECT CAST(1 AS decimal(21,20)) * CAST(123 AS DECIMAL(13,9)) FROM SYSIBM.DUAL;

1
---------------------------------
SQL0413N  Overflow occurred during numeric data type conversion.
SQLSTATE=22003

db2 => DESCRIBE SELECT CAST(1 AS decimal(21,20)) * CAST(123 AS DECIMAL(13,9)) FROM SYSIBM.DUAL;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 484   DECIMAL               31,29  1                                         1
123が3桁で入らないのでエラーとなる!

db2 => DESCRIBE SELECT CAST(1 AS decimal(21,20)) * CAST(123 AS DECIMAL(13,8)) FROM SYSIBM.DUAL;

 Column Information

 Number of columns: 1

 SQL type              Type length  Column name                     Name length
 --------------------  -----------  ------------------------------  -----------
 484   DECIMAL               31,28  1                                         1

db2 => SELECT CAST(1 AS decimal(21,20)) * CAST(123 AS DECIMAL(13,8)) FROM SYSIBM.DUAL;

1
---------------------------------
 123.0000000000000000000000000000

  1 record(s) selected.

コメント

人気の投稿