使用REGEXP_SUBSTR插入表

时间:2016-07-19 08:55:12

标签: plsql

我正在尝试将表格插入表格中:

'MARIE,CLAIRE,99999|RIM,CHAVANE,66666|RANA,LEONNE,33333';

我的表中应该有三行,如下:

NAME   LAST_NAME PHONE_NUMBER  
-----------------------------
MARIE  CLAIRE    99999
RIM    CHAVANE   66666                      
RANA   LEONNE    33333  

但是我只检索了第一行重复 你能帮忙吗?

以下是剧本:

DECLARE
  NAME         VARCHAR2(200):=NULL ;
  LAST_NAME    VARCHAR2(200):=NULL ;
  PHONE_NUMBER VARCHAR2(200):=NULL ;
  CHAINE       VARCHAR2(200):=NULL ;
  i            NUMBER       :=0;
  n            NUMBER       :=0;
BEGIN
  CHAINE :='MARIE,CLAIRE,99999|RIM,CHAVANE,66666|RANA,LEONNE,33333';

  FOR  i in 1..10
  LOOP
    NAME         := REGEXP_SUBSTR(CHAINE,'[^,]+', 1, 1);
    LAST_NAME    := REGEXP_SUBSTR(CHAINE,'[^,]+', 1, 2);
    PHONE_NUMBER := REGEXP_SUBSTR(CHAINE,'[^,$|]+', 1, 3);
    INSERT INTO test_oum VALUES (NAME,LAST_NAME,PHONE_NUMBER);
    COMMIT;
  END LOOP;

  dbms_output.put_line('NAME        '  || NAME );
  dbms_output.put_line('LAST_NAME     '  || LAST_NAME );
  dbms_output.put_line('PHONE_NUMBER    '  || PHONE_NUMBER );

END;

3 个答案:

答案 0 :(得分:1)

通常,当使用普通的旧SQL进行操作时,应避免使用PL / SQL结构。通常,生成的代码将更简洁,更快捷。在这里,您将看到一个带有单个SQL insert-select-statement的示例:

declare
  v_chaine constant varchar2(32767) := 
    'MARIE,CLAIRE,99999|RIM,CHAVANE,66666|RANA,LEONNE,33333';
begin
  -- note: missing column names in insert statement is not recommended
  insert into test_oum
  with
  -- split single string on '|'
  r(str) as (
    select     regexp_substr(v_chaine ,'[^|]+', 1, level) from dual
    connect by regexp_substr(v_chaine ,'[^|]+', 1, level) is not null
  )
  select
   regexp_substr(str,'[^,]+', 1, 1) as first_name
  ,regexp_substr(str,'[^,]+', 1, 2) as last_name
  ,regexp_substr(str,'[^,]+', 1, 3) as phone_number
  from r
  ;
end;
/

参见例如Oracle 11g: INSERT SELECT with WITH statement

答案 1 :(得分:0)

你遇到的问题是,对于所有循环,你总是在相同的逗号(即第一个,第二个和第三个)上执行子字符串。 “Chaine”变量未被修改,因此您始终检索相同的值。

我认为你需要做类似以下的事情:

DECLARE
  NAME         VARCHAR2(200):=NULL ;
  LAST_NAME    VARCHAR2(200):=NULL ;
  PHONE_NUMBER VARCHAR2(200):=NULL ;
  CHAINE       VARCHAR2(200):=NULL ;
  i            NUMBER       :=0;
  n            NUMBER       :=0;
BEGIN
  CHAINE :='MARIE,CLAIRE,99999|RIM,CHAVANE,66666|RANA,LEONNE,33333';

  FOR cValue IN (
    SELECT REGEXP_SUBSTR(chaine ,'[^|]+',1,LEVEL) val FROM DUAL
    connect BY REGEXP_SUBSTR(chaine ,'[^|]+',1,LEVEL) IS NOT NULL
  )
  LOOP
    NAME         := REGEXP_SUBSTR(cValue.val,'[^,]+', 1, 1);
    LAST_NAME    := REGEXP_SUBSTR(cValue.val,'[^,]+', 1, 2);
    PHONE_NUMBER := REGEXP_SUBSTR(cValue.val,'[^,]+', 1, 3);

    dbms_output.put_line('NAME         '  || NAME );
    dbms_output.put_line('LAST_NAME    '  || LAST_NAME );
    dbms_output.put_line('PHONE_NUMBER '  || PHONE_NUMBER );

    INSERT INTO test_oum VALUES (NAME,LAST_NAME,PHONE_NUMBER);
    COMMIT;
  END LOOP;
END;

这会将字符串拆分为管道字符,并循环遍历每个字符串。然后,每次通过分割逗号来提取姓名,姓氏和电话号码。

答案 2 :(得分:0)

你不需要声明"我int:= 0"

DECLARE
  NAME         VARCHAR2(200):=NULL ;
  LAST_NAME    VARCHAR2(200):=NULL ;
  PHONE_NUMBER VARCHAR2(200):=NULL ;
  CHAINE       VARCHAR2(200):=NULL ;
  n            NUMBER       :=0;
BEGIN
  CHAINE :='MARIE,CLAIRE,99999|RIM,CHAVANE,66666|RANA,LEONNE,33333';

  FOR  i in 1..10
  LOOP
    NAME         := REGEXP_SUBSTR(CHAINE,'[^,]+', 1, 1);
    LAST_NAME    := REGEXP_SUBSTR(CHAINE,'[^,]+', 1, 2);
    PHONE_NUMBER := REGEXP_SUBSTR(CHAINE,'[^,$|]+', 1, 3);
    INSERT INTO test_oum VALUES (NAME,LAST_NAME,PHONE_NUMBER);
    COMMIT;
  END LOOP;

  dbms_output.put_line('NAME        '  || NAME );
  dbms_output.put_line('LAST_NAME     '  || LAST_NAME );
  dbms_output.put_line('PHONE_NUMBER    '  || PHONE_NUMBER );

END;