繁体   English   中英

Oracle PLSQL-如何将管道分隔的字符串值插入表中

[英]Oracle PLSQL - How to insert pipeseparated string values into a table

需求就像:

我有一个用|(Pipe)分隔的字符串。 我需要拉出每个字符串值并插入到表中。

例如:字符串就像A,B,C,D,E,F,L,R,X,Z

Table has all the columns from A to Z 

如果给定的字符串具有A值,则该列应插入“是”,否则插入“否”。 像这样,如果字符串具有值,则表中的对应列应变为“是”,否则为“否”。

我编写了一个过程,将其插入到不同的行中。


DECLARE 
LV_VUSR VARCHAR2(1000);
BEGIN
FOR J IN (SELECT COLUMN_VALUE FROM TABLE(MS_APPS_UTILITIES.SPLIT_STRING('A,B,D',','))) 
LOOP
  LV_VUSR := J.COLUMN_VALUE;

     INSert into dummy_v 
     values ('1', decode(J.column_value,'A','Y','N'),decode(J.column_value,'B','Y','N'),decode(J.column_value,'C','Y','N'),decode(J.column_value,'D','Y','N'));

END LOOP;
END;

我已经写了这个块,其中要为同一id插入多行。 有人可以帮忙吗?

一个带有5列的较小示例(您应该可以将其扩展到全部26个):

Oracle安装程序

CREATE TABLE table_name (
  id INT,
  A CHAR(1),
  B CHAR(1),
  C CHAR(1),
  D CHAR(1),
  E CHAR(1)
);

查询

INSERT INTO table_name
WITH data ( id, value ) AS (
  SELECT 1, 'A,B,E' FROM DUAL UNION ALL
  SELECT 2, 'B,E' FROM DUAL
)
SELECT d.id, 
       CASE WHEN COUNT( CASE WHEN t.COLUMN_VALUE = 'A' THEN 1 END ) > 0
            THEN 'Y' ELSE 'N' END, 
       CASE WHEN COUNT( CASE WHEN t.COLUMN_VALUE = 'B' THEN 1 END ) > 0
            THEN 'Y' ELSE 'N' END, 
       CASE WHEN COUNT( CASE WHEN t.COLUMN_VALUE = 'C' THEN 1 END ) > 0
            THEN 'Y' ELSE 'N' END, 
       CASE WHEN COUNT( CASE WHEN t.COLUMN_VALUE = 'D' THEN 1 END ) > 0
            THEN 'Y' ELSE 'N' END, 
       CASE WHEN COUNT( CASE WHEN t.COLUMN_VALUE = 'E' THEN 1 END ) > 0
            THEN 'Y' ELSE 'N' END
FROM   data d,
       TABLE(
        CAST(
          MULTISET(
            SELECT REGEXP_SUBSTR( d.value, '[^,]+', 1, LEVEL )
            FROM   DUAL
            CONNECT BY LEVEL <= REGEXP_COUNT( d.value, '[^,]+' )
          ) AS SYS.ODCIVARCHAR2LIST
        )
       ) t
GROUP BY d.id;

输出

SELECT * FROM table_name;

        ID A B C D E
---------- - - - - -
         1 Y Y N N Y 
         2 N Y N N Y 

或使用简短存储函数的解决方案:

Oracle安装程序

CREATE TYPE stringlist IS TABLE OF VARCHAR2(20);
/

CREATE FUNCTION split_String(
  i_str    IN  VARCHAR2,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN stringlist DETERMINISTIC
AS
  p_result       stringlist := stringlist();
  p_start        NUMBER(5) := 1;
  p_end          NUMBER(5);
  c_len CONSTANT NUMBER(5) := LENGTH( i_str );
  c_ld  CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := INSTR( i_str, i_delim, p_start );
    WHILE p_end > 0 LOOP
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
      p_start := p_end + c_ld;
      p_end := INSTR( i_str, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1 THEN
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
    END IF;
  END IF;
  RETURN p_result;
END;
/

查询

INSERT INTO table_name
WITH data ( id, value ) AS (
  SELECT 1, 'A,B,E' FROM DUAL UNION ALL
  SELECT 2, 'B,E' FROM DUAL
)
SELECT id,
       CASE WHEN 'A' MEMBER OF vs THEN 'Y' ELSE 'N' END,
       CASE WHEN 'B' MEMBER OF vs THEN 'Y' ELSE 'N' END,
       CASE WHEN 'C' MEMBER OF vs THEN 'Y' ELSE 'N' END,
       CASE WHEN 'D' MEMBER OF vs THEN 'Y' ELSE 'N' END,
       CASE WHEN 'E' MEMBER OF vs THEN 'Y' ELSE 'N' END
FROM  (
  SELECT id,
         split_String( value ) AS vs
  FROM   data
);

输出

SELECT * FROM table_name;

        ID A B C D E
---------- - - - - -
         1 Y Y N N Y 
         2 N Y N N Y 

这可能被过度简化,但是如果您可以依靠输入数据的质量,为什么不这样做呢?

INSERT INTO table_name
WITH data ( id, value ) AS (
  SELECT 1, 'A,B,E' FROM DUAL UNION ALL
  SELECT 2, 'B,E' FROM DUAL
)
SELECT d.id,
       CASE WHEN INSTR(d.value,'A') > 0 THEN 'Y' ELSE 'N' END A,
       CASE WHEN INSTR(d.value,'B') > 0 THEN 'Y' ELSE 'N' END B,
       CASE WHEN INSTR(d.value,'C') > 0 THEN 'Y' ELSE 'N' END C,
       CASE WHEN INSTR(d.value,'D') > 0 THEN 'Y' ELSE 'N' END D,
       CASE WHEN INSTR(d.value,'E') > 0 THEN 'Y' ELSE 'N' END E
FROM   data d

可以改用REGEXP_INSTR覆盖输入数据中的一些细微变化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM