oracle 使用SQL Loader从单个列加载多行

juud5qan  于 2023-04-29  发布在  Oracle
关注(0)|答案(2)|浏览(203)

我有一个需求,我需要使用SQL加载器将数据从数据文件加载到表中。然而,对于类似的通道,数据将以单行提供。ROW_ID是主键,使用序列生成。IDENTIFY是内部通道标识符。IDENTIFY不能作为主键,因为它将违反第一范式。下面是数据文件:

IDENTIFY|CHANNEL_NAME|CHANNEL_PARTNERS                                                  |LOAD_DATE
1-ED    |WEBSITE     |"redbus","abhibus","amazon travel","irctc"                        |02-FEB-2022
1-LP    |WALKIN      |"physical reservation","printed reservation","current reservation"|04-FEB-2022

但是,要加载到数据库中的数据是这样使用SQLLDR的。

IDENTIFY   CHANNEL_NAME   CHANNEL_PARTNERS     LOAD_DATE
1-ED       WEBSITE        redbus               02-FEB-2022
1-ED       WEBSITE        abhibus              02-FEB-2022
1-ED       WEBSITE        amazon travel        02-FEB-2022
1-ED       WEBSITE        irctc                02-FEB-2022
1-LP       WALKIN         physical reservation 04-FEB-2022
1-LP       WALKIN         printed reservation  04-FEB-2022
1-LP       WALKIN         current reservation  04-FEB-2022

下面是CTL文件。

load data 
infile 'mchannel.txt'
append into table master_channel
fields terminated by "|"
(
 row_id  "chan_seq.nextval",
 identify,
 channel_name,
 channel_partners,
 load_date
)

如何使用SQLLDR实现这一点?

von4xj4u

von4xj4u1#

首先可以创建辅助表

CREATE TABLE master_channel_
(                                                                                                                                                                
 identify           VARCHAR2(15),
 channel_names      VARCHAR2(25), 
 channel_partners   VARCHAR2(500),
 load_date          VARCHAR2(25)  
);

并通过以下方式将数据加载到其中

$ . mchannel.sh

它的内容是

sqlldr userid="un/pwd"@thedb control=mchannel.ctl log=mchannel.log bad=mchannel.bad errors=99999999 direct=y

.ctl文件是

OPTIONS(skip=1)
LOAD DATA                                                                                                                                                                           
 INFILE 'mchannel.txt' "str '\n'"                                                                                                           
 TRUNCATE INTO TABLE master_channel_                                                                                                                      
 FIELDS TERMINATED BY '|'                                                                                                                                                         
 (                                                                                                                                                                
  identify           CHAR(15)  "TRIM(:identify)",
  channel_names      CHAR(25)  "TRIM(:channel_names)", 
  channel_partners   CHAR(500) "TRIM(:channel_partners)",
  load_date          CHAR(25)  "TRIM(:load_date)"
 )

然后使用以下查询

INSERT INTO master_channel(identify,channel_names,channel_partners,load_date)
 SELECT m.identify,
        m.channel_names,
        TRIM( BOTH '"' FROM REGEXP_SUBSTR(m.channel_partners,'[^,]+',1,level)),
        TO_DATE(m.load_date,'dd-MON-yyyy')
   FROM master_channel_ m
CONNECT BY level <= REGEXP_COUNT(m.channel_partners,',')+1
    AND prior sys_guid() IS NOT NULL
    AND prior m.identify = m.identify;

在应用所需的转换时插入到主表中,其中假定该表创建为

CREATE TABLE master_channel
(                          
 row_id             NUMBER generated always as identity,                                                                                                                                      
 identify           VARCHAR2(15),
 channel_names      VARCHAR2(25), 
 channel_partners   VARCHAR2(500),
 load_date          DATE  
)
ykejflvf

ykejflvf2#

正如Paul W所建议的,一个简单的AWK完成了准备文件的工作,您可以借此机会删除双引号(和/或更改分隔符,如您所愿):

awk -F '|' '{split($3,a,/,/)}; { for (s in a) { print $1 "|" $2 "|" substr( a[s], 2, length(a[s])-2 ) "|" $4 }  }' 

1-ED|WEBSITE|abhibus|02-FEB-2022
1-ED|WEBSITE|amazon travel|02-FEB-2022
1-ED|WEBSITE|irctc|02-FEB-2022
1-ED|WEBSITE|redbus|02-FEB-2022
1-LP|WALKIN|printed reservation|04-FEB-2022
1-LP|WALKIN|current reservation|04-FEB-2022
1-LP|WALKIN|physical reservation|04-FEB-2022

相关问题