sql - Oracle SQL Loader 控制文件:使用 WHEN 上传不同表中的标头
问题描述
我收到一个文件,其中包含:
- 一个标题,以字符串标题开头,后跟一些列;
- 正文:第一行(标题)之后的所有其他行。
我知道只有标题会以字符串“HEADER”开头,所以我想我可以在我的控制文件中使用 WHEN 条件检查它,这是必要的,因为我必须将标题的内容插入表中,并将正文插入另一个表,所以我创建了以下控制文件:
OPTIONS (READSIZE=512000000,bindsize=512000000,rows=64000, ERRORS=100000)
LOAD DATA
characterset UTF8 length semantics byte
REPLACE
INTO TABLE <TABLE_1>
WHEN (1:6) != 'HEADER'
fields terminated by "|"
TRAILING NULLCOLS
(
ANNO INTEGER EXTERNAL,
COD_PRODOTTO CHAR(12) "TRIM (:COD_PRODOTTO)",
DESCRIZIONE_PRODOTTO CHAR(254) "TRIM (SUBSTRB(:DESCRIZIONE_PRODOTTO,1,254))",
COD_PADRE CHAR(12) "TRIM (:COD_PADRE)",
FOGLIA CHAR(1) "TRIM (:FOGLIA)",
COD_STRUTTURA CHAR(10) "TRIM (:COD_STRUTTURA)",
TIPO_STRUTTURA CHAR(10) "TRIM (:TIPO_STRUTTURA)"
)
INTO TABLE <TABLE_2>
WHEN (1:6) = 'HEADER'
fields terminated by "|"
TRAILING NULLCOLS
(
HEADER FILLER,
ANNO INTEGER EXTERNAL,
COD_STRUTTURA CHAR(12) "TRIM (:COD_STRUTTURA)",
TIPO_STRUTTURA CHAR(12) "TRIM (:TIPO_STRUTTURA)",
TIPO_INVIO CHAR(5) "TRIM (:TIPO_INVIO)",
DATA_RICEZIONE "sysdate"
)
但我知道正文行已正确插入,但标题行未正确插入(它说“ANNO”是一个无效数字,但不是)。
“酷”的部分是,如果我反转插入标题而不是正文的位置(再次无效的“ANNO”)。
查看日志,它似乎读取了忽略 where 的两个表的结构,就像它是单个表的内容一样,因为我有:
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
ANNO FIRST * | CHARACTER
COD_PRODOTTO NEXT 12 | CHARACTER
SQL string for column : "TRIM (:COD_PRODOTTO)"
DESCRIZIONE_PRODOTTO NEXT 254 | CHARACTER
SQL string for column : "TRIM (SUBSTRB(:DESCRIZIONE_PRODOTTO,1,254))"
COD_PADRE NEXT 12 | CHARACTER
SQL string for column : "TRIM (:COD_PADRE)"
FOGLIA NEXT 1 | CHARACTER
SQL string for column : "TRIM (:FOGLIA)"
COD_STRUTTURA NEXT 10 | CHARACTER
SQL string for column : "TRIM (:COD_STRUTTURA)"
TIPO_STRUTTURA NEXT 10 | CHARACTER
SQL string for column : "TRIM (:TIPO_STRUTTURA)"
Table <TABLE_2>, loaded when 1:6 = 0X484541444552(character 'HEADER')
Insert option in effect for this table: REPLACE
TRAILING NULLCOLS option in effect
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
HEADER NEXT * | CHARACTER
(FILLER FIELD)
ANNO NEXT * | CHARACTER
COD_STRUTTURA NEXT 12 | CHARACTER
SQL string for column : "TRIM (:COD_STRUTTURA)"
TIPO_STRUTTURA NEXT 12 | CHARACTER
SQL string for column : "TRIM (:TIPO_STRUTTURA)"
TIPO_INVIO NEXT 5 | CHARACTER
SQL string for column : "TRIM (:TIPO_INVIO)"
DATA_RICEZIONE NEXT * | CHARACTER
SQL string for column : "sysdate"
所以第二个从 NEXT 而不是 FIRST 开始,所以我认为所有的列都被移动了。
我尝试为第二个表添加“POSITION(1) FILLER”,但我得到了关于类型的其他错误。
我的控制文件有什么问题?
解决方案
这是您正在执行的操作的简化示例。为什么要简化?因为你没有提供测试用例,我也不想输入那么多。
示例表:
SQL> create table t1_header
2 (header varchar2(10),
3 anno number,
4 cod_struttura varchar2(10)
5 );
Table created.
SQL> create table t2_body
2 (anno number,
3 cod_prodotto varchar2(12),
4 descrizione_prodotto varchar2(10)
5 );
Table created.
SQL>
控制文件;它包含要加载的数据。我首先加载标题表,接下来是正文:
load data
infile *
replace
into table t1_header
when (1:6) = 'HEADER'
fields terminated by "|"
trailing nullcols
(header filler,
anno,
cod_struttura
)
into table t2_body
when (1:6) <> 'HEADER'
fields terminated by "|"
trailing nullcols
(anno position(1),
cod_prodotto,
descrizione_prodotto
)
begindata
HEADER|2021|test 1
2019|test2|descr t2
2020|test3|descr t3
加载会话和结果:
SQL> $sqlldr scott/tiger control=test1.ctl log=test1.log
SQL*Loader: Release 11.2.0.2.0 - Production on Pon Ruj 27 19:27:14 2021
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 2
Commit point reached - logical record count 3
SQL> select * From t1_header;
HEADER ANNO COD_STRUTT
---------- ---------- ----------
2021 test 1
SQL> select * From t2_body;
ANNO COD_PRODOTTO DESCRIZION
---------- ------------ ----------
2019 test2 descr t2
2020 test3 descr t3
SQL>
在我看来,关键时刻是指示 SQL*Loader 再次重新处理同一个文件。如何?通过设置position
:
(anno position(1),
如您所见,两个表都已加载,包含所有示例行。
推荐阅读
- excel - 使用 MS Excel 驱动程序连接 odbc 后打开 excel 文件时出错
- go - 为什么 map[]interface{} 不采用 map[]SpecificInterface
- java - 如果使用 Android 后台服务,Flutter 会卡在“等待天文台端口可用”
- java - camunda 拦截业务流程执行
- google-bigquery - 子查询中case语句后的BigQuery连接表
- python - 是否可以从 python 代码中删除所有 __future__ 语句,而不影响其使用 python 3.7.1 的功能?
- angular - Angular 前端显示 Laravel 后端存储的图像
- css - 有没有办法对齐
在 HTML5 中?
- excel - 在不移动单元格的情况下删除重复项
- spring - 使用 Spring Cloud 连接器和 HikariCP 配置 Postgresql sslrootcert