首页 > 解决方案 > 使用集合在包含虚拟列的 oracle 表中插入记录

问题描述

我打算在一个表中插入大约 500 万条记录,因此决定使用集合。该表有 300 多列,其中一列是虚拟列,例如 col2。

我的代码可以正常工作,但有一些Q查询。任何指针都会有很大帮助。

01 DECLARE
02   TYPE test IS TABLE OF SAMPLE_TBL%ROWTYPE;
03   l_tab test := test();            
04   BEGIN
05     l_tab.extend;
07     l_tab(l_tab.last).col1   := 1;
08     -- l_tab(l_tab.last).col2:= 1; VIRTUAL col
09     l_tab(l_tab.last).col3   := 1; 
10     ..
11     l_tab(l_tab.last).col300 := 1;
12   
13     FORALL i IN l_tab.first .. l_tab.last
17       INSERT INTO SAMPLE_TBL(
18         col1,
19         -- col2,
20         col3,
21         --
22       col300  
23     ) VALUES (
24       l_tab(i).col1,
25       -- l_tab(i).col2,
26       l_tab(i).col3,
27       --
28       l_tab(i).col300
29     );
30     COMMIT;
31   END;
32 /   

:由于 col2 是虚拟的,我必须使用列名(第 18-22 行)准备插入语句。代码看起来很混乱,因为我必须为 300 多个 cols 做。有什么办法可以排除虚拟列但仍然使用类似的东西 INSERT INTO SAMPLE_TBL values(val1,val3,..,val300);

:从 07-11 行开始,使用实际的列名分配值,就像这样,l_tab(l_tab.last).col1 := 1;那么,有没有办法告诉插入语句(或任何其他功能)插入 l_tab(l_tab.last)。col1进入col1,而不必再次按顺序编写列名(第 24-28 行) - 类似于映射哈希。

标签: arraysoracleplsql

解决方案


CREATE TABLE sample_tbl
(col1 number,
 col2 AS (col1+1),
 col3 number,
 col4 number,
 col5 number);

创建一个没有虚拟列的视图:

CREATE VIEW v_sample_tbl AS
SELECT col1, col3, col4, col5 FROM sample_tbl;

在表中插入失败:

DECLARE
  TYPE test IS TABLE OF SAMPLE_TBL%ROWTYPE;
  l_tab test := test();            
  BEGIN
    l_tab.extend;
    l_tab(l_tab.last).col1 := 1;
    l_tab(l_tab.last).col3 := 1; 
    l_tab(l_tab.last).col4 := 1; 
    l_tab(l_tab.last).col5 := 1;

    FORALL i IN l_tab.first .. l_tab.last
      INSERT INTO sample_tbl VALUES l_tab(i);
      COMMIT;
  END;
/


ERROR at line 1:
ORA-54013: INSERT operation disallowed on virtual columns
ORA-06512: at line 11

插入视图作品:

DECLARE
  TYPE test IS TABLE OF v_sample_tbl%ROWTYPE;
  l_tab test := test();            
  BEGIN
    l_tab.extend;
    l_tab(l_tab.last).col1 := 1;
    l_tab(l_tab.last).col3 := 1; 
    l_tab(l_tab.last).col4 := 1; 
    l_tab(l_tab.last).col5 := 1;

    FORALL i IN l_tab.first .. l_tab.last
      INSERT INTO v_sample_tbl VALUES l_tab(i);
      COMMIT;
  END;
/   

SQL> select * from sample_tbl;

      COL1       COL2       COL3       COL4       COL5
---------- ---------- ---------- ---------- ----------
         1          2          1          1          1

推荐阅读