将浮动数据加载到Oracle的外部表中

时间:2017-09-28 18:47:50

标签: sql oracle external-tables

我在将FLOAT数据加载到外部表时遇到了麻烦......数据类似:+00000700000,00。任何想法如何做到这一点? FLOAT EXTERNALFLOAT(15)不起作用......当然在CREATE声明中我有FLOAT列。

FLOAT只会加载前4个字符...将其保留为CHAR(15)也不起作用...

create or replace PROCEDURE LOAD_TO_EXTERNAL AS
  PATH_FILE VARCHAR2(100) := 'TEST_FILE.TXT';
  DELIMETER VARCHAR2(100) := '-';
  DATE_FORMATTING VARCHAR2(100) := 'YYYY-MM-DD';
  STMT VARCHAR2(5000);
BEGIN
  STMT := 'CREATE TABLE "TEST_EXT"
    (
      DATA DATE,
      NAME VARCHAR2(40),
      AGGR_NUM FLOAT(27)
    )
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER DEFAULT DIRECTORY MY_DIR ACCESS PARAMETERS
      (RECORDS DELIMITED BY ''' || DELIMETER || '''
      FIELDS LRTRIM (
          DATA CHAR(10) DATE_FORMAT DATE MASK ''' || DATE_FORMATTING || ''',
          NAME CHAR(40),
          AGGR_NUM FLOAT         )
      ) LOCATION (''' || PATH_FILE || ''')
    )
    REJECT LIMIT UNLIMITED';

    EXECUTE IMMEDIATE STMT;
END LOAD_TO_EXTERNAL;

2 个答案:

答案 0 :(得分:0)

首先,要将+00000700000,00之类的字符串转换为Oracle数字值,您需要类似to_number('+00000700000,00', 'S00000000000,00')的内容。

其次,您需要在加载程序的FIELDS部分进行任何字符到数字的转换。

第三,您可能不想自己指定FLOAT精度 - the precision for FLOAT is specified in binary digits,默认值为126,相当于38位小数。您正在使用FLOAT(27),它看起来大概是10个小数位,但您正在加载13位数字。如果您不关心ANSI可移植性,那么您也可以使用NUMBER数据类型,这也是Oracle在幕后使用的数据类型。

试试这个,让我知道它是如何工作的。

create or replace PROCEDURE LOAD_TO_EXTERNAL AS
  PATH_FILE VARCHAR2(100) := 'TEST_FILE.TXT';
  DELIMETER VARCHAR2(100) := '-';
  DATE_FORMATTING VARCHAR2(100) := 'YYYY-MM-DD';
  STMT VARCHAR2(5000);
BEGIN
  STMT := 'CREATE TABLE "TEST_EXT"
    (
      DATA DATE,
      NAME VARCHAR2(40),
      AGGR_NUM FLOAT
    )
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER DEFAULT DIRECTORY MY_DIR ACCESS PARAMETERS
      (RECORDS DELIMITED BY ''' || DELIMETER || '''
      FIELDS LRTRIM (
          DATA CHAR(10) DATE_FORMAT DATE MASK '' || DATE_FORMATTING || '',
          NAME CHAR(40),
          AGGR_NUM "to_number(:AGGR_NUM, '''S00000000000,00''')" )
      ) LOCATION (''' || PATH_FILE || ''')
    )
    REJECT LIMIT UNLIMITED';

    EXECUTE IMMEDIATE STMT;
END LOAD_TO_EXTERNAL;

答案 1 :(得分:0)

在Oracle中创建外部表的功能具有有限的数据转换功能。如果您想要更强大的解决方案,可以使用sql loader和特定的控制文件来转换数据。

另一种解决方案可能是创建外部表以访问文件中的数据,然后创建一个附加表,使用create table作为select将数据加载到其中...并进行适当的转换。根据您的性能要求,您还可以创建视图以进行转换。

您的数据存在的问题是,在将文本转换为浮点数时,oracle并不喜欢加号。以下示例可以使用,但会留下一个单独的符号列,需要单独处理。

CREATE TABLE TEST_EXT
(
  DATEX date,
  NAMEX VARCHAR2(5),
  SGN VARCHAR2(1),
  FLT float
)
ORGANIZATION EXTERNAL
(
  TYPE ORACLE_LOADER DEFAULT DIRECTORY MY_DIR 
  ACCESS PARAMETERS 
    (
        RECORDS FIXED 30 FIELDS
        (
            DATEX CHAR(10) date_format date mask 'YYYY-MM-DD',
            NAMEX CHAR(5),
            SGN CHAR(1),
            FLT CHAR(14) 
        )
    ) LOCATION ('test.txt')
)
REJECT LIMIT UNLIMITED;

的test.txt

2017-09-24ABCDE+00000700000.99

查询表格:

select datex, namex, sgn, flt from test_ext;

输出:

DATEX      NAMEX S        FLT
---------- ----- - ----------
2017-09-24 ABCDE +  700000.99