scala Oracle Number数据类型的Clickhouse数据类型模拟

vd2z7a6w  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(61)

(Clickhouse-www.example.com,Oracle-11.2.0.3.0).我的任务是将数据从Oracle表加载到Clickhouse表中(使用scala代码)。
在甲骨文中,表是用脚本 Package 的:

create table EAIST_LOT_SS
(
  id             NUMBER not null,
  registrynumber VARCHAR2(19) not null,
  tendersubject  VARCHAR2(2048),
  lotnumber      NUMBER not null,
  lotprice       NUMBER
);

column COLUMN_NAME format a15
column DATA_TYPE format a15

select column_name, data_type, nullable, data_length, data_precision, data_scale
from user_tab_columns where table_name ='EAIST_LOT_SS';

COLUMN_NAME     DATA_TYPE       NULLABLE DATA_LENGTH DATA_PRECISION DATA_SCALE
--------------- --------------- -------- ----------- -------------- ----------
ID              NUMBER          N                 22                
REGISTRYNUMBER  VARCHAR2        N                 19                
TENDERSUBJECT   VARCHAR2        Y               2048                
LOTNUMBER       NUMBER          N                 22                
LOTPRICE        NUMBER          Y                 22

字符串
在clickhouse中,表格上写满了脚本:

create table data.eaist_lot
(
  id                  UInt8 not null,
  registrynumber      FixedString(19) not null,
  tendersubject       FixedString(2048),
  lotnumber           Decimal64(18) not null,
  lotprice            Decimal64(18)
)ENGINE = MergeTree()
PRIMARY KEY (id);


scala代码,尝试在table中添加一行。

def saveToClickhouse(table: String, chConn: ClickHouseConnection): Unit = {
    val ps: PreparedStatement = chConn.prepareStatement(
      s"""insert into ${table}
        |select id, registrynumber, tendersubject, lotnumber, lotprice
        |from
        |input('id             UInt8,
        |       registrynumber FixedString(19),
        |       tendersubject  FixedString(2048),
        |       lotnumber      Decimal64(18),
        |       lotprice       Decimal64(18)
        |      ')
        |""".stripMargin)

    ps.setInt(1,1)
    ps.setString(2,"str 222")
    ps.setString(3,"str 333")
    ps.setDouble(4,1.2)
    ps.setDouble(5,2.3)

    ps.addBatch()
    ps.executeBatch()
  }


我有错误:线程"main"中的异常java. lang. IllegalArgumentException:BigDecliter(120000000000000000000000000)应该介于-100000000000000000000和10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
在Clickhouse中,Number(不设置精度和比例)的最佳模拟是什么?

mznpcxlj

mznpcxlj1#

在Oracle中,NUMBER数据类型是:

内置数据类型汇总

| 代码|数据类型|描述|
| --|--|--|
| 2 |NUMBER [ (p [, s]) ]个|具有精度p和小数位数s的数字。精度p的范围可以从1到38。小数位数s的范围可以从-84到127。精度和小数位数都是十进制数字。NUMBER值需要1到22个字节。|
...
使用以下格式指定整数:

NUMBER(p)

字符串
这表示一个定点数,精度为p,小数位数为0,等价于NUMBER(p,0)
使用以下格式指定浮点数:

NUMBER


缺少精度和小数位数指示符将指定Oracle数字的最大范围和精度。
因此,没有指定精度或小数位数的NUMBER等效于NUMBER(38,*),后者具有最大精度和未指定小数位数,是一个精确的浮点数。
Clickhouse includes the numeric data types

  • 整数类型:有符号和无符号整数(UInt 8,UInt 16,UInt 32,UInt 64,UInt 128,UInt 256,Int 8,Int 16,Int 32,Int 64,Int 128,Int 256)
  • 浮点数:浮点数(浮点32和浮点64)和十进制值

其中DECIMAL文档指出:
有符号定点数,在加、减、乘运算中保持精度。对于除法,最低有效位被丢弃(不舍入)。

参数

  • P- precision。有效范围:[ 1:76 ]。确定数字可以有多少个小数位(包括小数)。默认情况下,精度为10。
  • S- scale。有效范围:[ 0:P ]。确定小数可以有多少位小数。

Decimal(P)等价于Decimal(P, 0)。同样,语法Decimal等价于Decimal(10, 0)
取决于P参数值Decliter(P,S)是以下的同义词:

  • P从[ 1:9 ] -对于Decimal32(S)
  • P来自[ 10:18 ] -对于Decimal64(S)
  • P来自[ 19:38 ] -对于Decimal128(S)
  • P来自[ 39:76 ] -对于Decimal256(S)

因此DECIMAL是一个定点数。
Clickhouse似乎没有与Oracle的NUMBER数据类型相同的等效数据类型。
您应该查看NUMBER列中包含的数据:

  • 如果你的列只包含整数值,那么你实际上是在使用NUMBER作为NUMBER(38,0),在Clickhouse中可以是Int128UInt128
  • 如果您的数字列包含定点小数值,并且将该列指定为NUMBER(38, s)是合适的,那么在Clickhouse中将是Decimal128(s)(假设0 ≤ s ≤ 38)。
  • 如果你真的使用NUMBER(或NUMBER(38,*))在Oracle中支持的全部精度和小数位数,那么Clickhouse似乎不支持该范围的值,你可以使用Float64来近似值,或者可以将值存储为字符串。

相关问题