Oracle 流水线表函数并将结果插入到 Oracle 表中

Posted

技术标签:

【中文标题】Oracle 流水线表函数并将结果插入到 Oracle 表中【英文标题】:Oracle pipelined table function and insert results into an Oracle table 【发布时间】:2019-08-28 13:43:56 【问题描述】:

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

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

SELECT column_value as val
FROM   TABLE(split(',AA,BB,CC,,,FF,GG,,,HH,'))

val的列别名下返回11行数据

val
----
NULL
AA
BB
CC,
NULL
NULL
FF
GG
NULL
NULL
HH

现在我还有一个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)
);

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

基本上想把每一行插入到我的表中。

【问题讨论】:

msg_log 有 11 列,而您的 split 函数只返回一列(11 行但 1 列)。 insert into msg_log(没有明确的列列表)期望 11 列,因此出现错误。 @NickKrasnov 好的,那么有没有办法根据我的问题实现我所追求的目标,即拆分每一行并插入列? 您是否希望旋转 split() 函数产生的结果? 您的列表有 12 个值(不是 11 个),因为结尾有一个逗号,所以第 12 个值将是 NULL 【参考方案1】:

Oracle 设置

this split function 的流水线版本:

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;
/

插入

只需添加一个行号和枢轴:

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 ) )

输出

SELECT * FROM msg_log;
C001 | C002 | C003 | C004 | C005 | C006 | C007 | C008 | C009 | C010 | C011 :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |机管局 | BB |抄送 | | |法郎 | GG | | |高

db小提琴here

【讨论】:

以上是关于Oracle 流水线表函数并将结果插入到 Oracle 表中的主要内容,如果未能解决你的问题,请参考以下文章

python中运行oracle查询并将结果插入到新的oracle表中的语法是啥?

将表数据类型从 SQL Server 转换为 Oracle 并将动态 SQL 数据插入到表数据类型

Oracle SQL3 3 嵌套表插入问题

使用 DataTable 中的 OracleDataAdapter 更新记录并将记录插入 Oracle 表

Oracle中把一张表查询结果插入到另一张表中

将一个表的查询结果插入到另一个表中(oracle、mysql、sql 、GP)