Oracle 管道化表函数并将结果插入到 Oracle 表中

ton*_*nyf 2 sql oracle oracle11g sql-insert

我正在使用 Oracle 管道表函数,并根据返回的记录,我想将每行数据插入到 Oracle 表中,该表具有完全相同的列数,即:

我写了一个split函数,它return type pipelined一切正常。

SELECT column_value as val
FROM   TABLE(split(',AA,BB,CC,,,FF,GG,,,HH,'))
Run Code Online (Sandbox Code Playgroud)

它在列别名下返回 11 行数据val

val
----
NULL
AA
BB
CC,
NULL
NULL
FF
GG
NULL
NULL
HH
Run Code Online (Sandbox Code Playgroud)

现在我还有一个msg_log具有以下定义的表:

CREATE TABLE msg_log
(
    C001    VARCHAR2(4000 BYTE),
    C002    VARCHAR2(4000 BYTE),
    C003    VARCHAR2(4000 BYTE),
    C004    VARCHAR2(4000 BYTE),
    C005    VARCHAR2(4000 BYTE),
    C006    VARCHAR2(4000 BYTE),
    C007    VARCHAR2(4000 BYTE),
    C008    VARCHAR2(4000 BYTE),
    C009    VARCHAR2(4000 BYTE),
    C010    VARCHAR2(4000 BYTE),
    C011    VARCHAR2(4000 BYTE)
);
Run Code Online (Sandbox Code Playgroud)

使用从管道函数返回的值split,我如何访问每条 11 条记录并将它们插入到我的msg_log表中。

基本上想取出每一行并将其插入到我的表中。

MT0*_*MT0 5

甲骨文设置

此 split 函数的流水线版本:

CREATE OR REPLACE FUNCTION split(
  i_str    IN  VARCHAR2,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN SYS.ODCIVARCHAR2LIST PIPELINED
AS
  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
      PIPE ROW( 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
      PIPE ROW ( SUBSTR( i_str, p_start, c_len - p_start + 1 ) );
    END IF;
  END IF;
END;
/
Run Code Online (Sandbox Code Playgroud)

插入

只需添加行号和枢轴:

INSERT INTO msg_log ( C001, C002, C003, C004, C005, C006, C007, C008, C009, C010, C011 )
SELECT *
FROM   (
  SELECT ROWNUM AS RN,
         COLUMN_VALUE As value
  FROM   TABLE( SPLIT( ',AA,BB,CC,,,FF,GG,,,HH,' ) )
)
PIVOT( MAX( value ) FOR rn IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ) )
Run Code Online (Sandbox Code Playgroud)

输出

SELECT * FROM msg_log;
Run Code Online (Sandbox Code Playgroud)
C001 | C002 | C003 | C004 | C005 | C006 | C007| C008 | C009 | C010 | C011
:--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :---
| AA | BB | 抄送 | | | FF | GG | | | 赫赫  

db<>在这里摆弄