【问题标题】:How to populate Oracle partition table如何填充 Oracle 分区表
【发布时间】:2013-06-25 08:01:40
【问题描述】:

我有这张桌子:

CREATE TABLE TBIGP
(
IDPER NUMBER(6),
DESCRIZIONE VARCHAR2(50),
DINS DATE
)
PARTITION BY LIST (IDPER)
(
PARTITION P201201 VALUES(201201),
PARTITION P201202 VALUES(201202),
PARTITION P201203 VALUES(201203),
PARTITION P201204 VALUES(201204),
PARTITION P201205 VALUES(201205),
PARTITION P201206 VALUES(201206),
PARTITION P201207 VALUES(201207),
PARTITION P201208 VALUES(201208),
PARTITION P201209 VALUES(201209),
PARTITION P201210 VALUES(201210),
PARTITION P201211 VALUES(201211),
PARTITION P201212 VALUES(201212),
PARTITION P201301 VALUES(201301),
PARTITION P201302 VALUES(201302),
PARTITION P201303 VALUES(201303),
PARTITION P201304 VALUES(201304),
PARTITION P201305 VALUES(201305),
PARTITION P201306 VALUES(201306),
PARTITION P201307 VALUES(201307),
PARTITION P201308 VALUES(201308),
PARTITION P201309 VALUES(201309),
PARTITION P201310 VALUES(201310),
PARTITION P201311 VALUES(201311),
PARTITION P201312 VALUES(201312),
PARTITION OTHER VALUES(DEFAULT)
);

现在我想以这种方式填充表格。使用诸如 forwhileloop 之类的迭代过程,我希望每个分区由 500000 条记录组成。为了精确,每个分区有 1 到 450000-500000 条记录,其中记录的数量是随机的(一个分区可以有 480000 条记录,另一个分区有 490000 或 450000 或 467890 条记录......)。

每生成 1000 条记录,我想做一次 commit

我不知道是否清楚。我很难用英语解释。谢谢。

编辑

类似这样的:

BEGIN
FOR i IN 1..24
LOOP
j:=1
z:=dbms_random.value(450000,500000)
WHILE j<=z
INSERT INTO T_BIG_P_1
VALUES (i, 'description', TRUNC(SYSDATE + DBMS_RANDOM.value(0,366))
IF MOD (j, 1000) = 0 THEN
COMMIT;
END IF;
j:=j+1;
END LOOP;
END;

exec DBMS_STATS.GATHER_TABLE_STATS('SH','T_BIG_P_1');

【问题讨论】:

  • "populate" - 你的数据来自哪里?另一个表,一个文件,一个过程?
  • Oracle 版本 11。我必须使用过程手动填充表。创建后,我想做一个带有循环的 plsql 过程来填充表。
  • 这似乎是对 PARTITION 机制的一种不寻常的使用——您确定要在名为 IDPER 的列中使用值为 201312 的 480000 行吗?
  • @GregHNZ 是的,仅用于锻炼。

标签: oracle loops plsql populate


【解决方案1】:

一个简单的匿名 PL/SQL 块应该适合您的需要:

DECLARE
  n INTEGER;
  idper INTEGER;
  s VARCHAR2(50);  
begin
  FOR year IN 2012..2013 LOOP
    FOR MONTH IN 1..12 LOOP
      idper := MONTH+(YEAR*100); 
      n := Dbms_Random.Value( low=>450000, high => 500000 );
      FOR i IN 1..n LOOP
        s := Dbms_Random.string('x',25)||' '||idper;
        INSERT INTO TBIGP (idper,DESCRIZIONE,DINS) VALUES (idper,s,SYSDATE); 
        IF Mod(i,1000) = 0 THEN
            COMMIT;
        END IF;
      END LOOP;
      COMMIT;
    END LOOP;
  END LOOP;
END;
/

请注意,可以通过使用 FORALL 语句进一步优化此代码,以从批量插入中受益。

【讨论】:

    【解决方案2】:

    要将过程中的数据插入表中,您可以使用如下代码

    CREATE OR REPLACE PROCEDURE my_filler  AS
    BEGIN
      FOR i IN 1 .. 500000 LOOP
    
        -- compute your idper, descrizione, dins and then insert into the table
        INSERT INTO tbigp (idper, descrizione, dins) VALUES (x, y, z);
    
        IF MOD(i, 10)=0 THEN
          dbms_application_info.set_module('my_filler', 'i='||i);
          COMMIT;
        END IF;
      END LOOP;
    END my_filler;
    /
    

    话虽如此,这将非常非常慢。我不建议

    1. 用过程填充它
    2. 在 1000 行后提交

    【讨论】:

    • 查看我的编辑.... 是这样的!在 IDPER 列中,有一种按月份划分的 2012/13 年的日期......类似于 201201、201202、201203 等等。我想在列中插入 2 年。
    • 分区名称重要还是可以使用间隔分区?
    猜你喜欢
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2018-09-07
    • 2020-01-06
    • 2013-03-23
    • 1970-01-01
    相关资源
    最近更新 更多