0

我有一个包含如下数据的文本文件:

A 123 JoeBSD1639973e7378790
A 344 TomGDF7393694e0902087
B 344 ZenGDF9838987e0849399

我已经使用 sqlldr 批量插入临时表,并且所有数据都在一个列中,因为我这里没有任何字段分隔符。

现在我想将这些数据分成如下列:

Section    Book1   Name   Book2   RollNo   Book3   RegNo
----------------------------------------------------------
A          123     Joe    BSD     1639973  e       7378790
A          344     Tom    GDF     7393694  e       0902087
B          344     Zen    GDF     9838987  e       0849399

我可以识别字段的方法是使用字符长度,例如 Section 是 2 长度,Book1 是 4,Name 是 3,Book2 是 3,RollNo 是 7,Book3 是 1,RegNo 是 7。

有人可以帮助我进行查询以进行此转换吗?

4

5 回答 5

1

you can use substr

eg:

with data as (select 'A 123 JoeBSD1639973e7378790' str from dual union all
select 'A 344 TomGDF7393694e0902087' from dual union all
select 'B 344 ZenGDF9838987e0849399' from dual)
select str,
       substr(str, 1, 1) section,
       substr(str, 3, 3) book1,
       substr(str, 7, 3) name,
       substr(str, 10, 3) book2,
       substr(str, 13, 7) rollno,
       substr(str, 20, 1) book3,
       substr(str, 21, 7) regno
  from data;
于 2013-03-13T12:20:29.900 回答
1

SubStr() 函数是您所需要的:http ://docs.oracle.com/cd/B19306_01/server.102/b14200/functions162​​.htm

您可能想考虑使用外部表而不是 SQL Loader 插入临时表,因为您可以更轻松地将 SQL 函数应用于文件数据并在读取文件期间拆分列。

于 2013-03-13T12:19:24.627 回答
1

我们还可以使用 UTL 文件从平面文件中提取数据,而 UTL 文件本身会将数据提取为字符串,因此您知道可以使用哪些长度SUBSTR来提取正确的列值,然后插入到临时表中

declare 
     f1 UTL_FILE.FILE_TYPE;
     V_str varchar(2000);
begin
     f1 := UTL_FILE.FOPEN('Directory','File_NAME.txt','W');
     loop
         UTL_FILE.GETLINE(F1,v_str);
         v1:=substr(v_str,1,2);
         v2:=substr(v_str,3,4);
         v3:=substr(v_str,7,3);
         v4:=substr(v_str,10,3);
         v5:=substr(v_str,13,7);
         v6:=substr(v_str,20,1);
         v7:=substr(v_str,21,7);
         insert into temp values(v1,v2,v3,v4,v5,v6,v7);
    end loop;
 exception
    when no_data_found then
       dbms_output.put_line('end reached');
end;
于 2013-03-13T13:38:26.990 回答
0

Here's an example:

Select trim(substr('B 344 ZenGDF9838987e0849399',1,2)) as Section, 
       trim(substr('B 344 ZenGDF9838987e0849399',3,4)) as Book1,
       trim(substr('B 344 ZenGDF9838987e0849399',7,3)) as Name,
       trim(substr('B 344 ZenGDF9838987e0849399',10,3)) as Book2,
       trim(substr('B 344 ZenGDF9838987e0849399',13,7)) as RollNo,
       trim(substr('B 344 ZenGDF9838987e0849399',20,1)) as Book2,
       trim(substr('B 344 ZenGDF9838987e0849399',21,7)) as RegionNo
from dual

I used trim to eliminate spaces; but maybe they are relevant?

于 2013-03-13T12:20:23.273 回答
0

这也可能有所帮助。我有类似的问题,并在 Oracle-Base 论坛中寻求帮助。此查询由 Tim - Oracle-Base.com 的版主编写:

SELECT REGEXP_SUBSTR(str, '[A-Z][a-z]+', 1, 1) col1,
       REGEXP_SUBSTR(str, '[A-Z]+', 1, 2) col2,
       REGEXP_SUBSTR(str, '[0-9]+', 1, 1) col3,
       REGEXP_SUBSTR(str, '[a-z]+', 1, 2) col4,
       REGEXP_SUBSTR(str, '[0-9]+', 1, 2) col5
  FROM
  (
   SELECT 'JoeBSD1639973e7378790' str FROM dual
  )
  /

COL1  COL2  COL3     COL4  COL5
-----------------------------------
Joe   BSD   1639973   e    7378790
于 2013-03-13T17:22:53.610 回答