Oracle使用增量编号更新每n行数

时间:2014-02-05 22:23:47

标签: sql oracle plsql sql-update

我有几个表需要使用从1开始的增量计数器为N(变量)行更新数字列(“BATCH”)。示例:如果表有1m条记录,其中250,000条记录适合在某个条件下,550k记录中的前100k应更新BATCH列的编号为1,第二个100k记录应更新为编号2,其余50k记录应更新为3。

以下是我的尝试:

    v_cnt:=0;

    <<LoopBatch>>LOOP
    v_cnt_sql:='SELECT count(*)     
                FROM '||v_in_skinny_table||' 
                WHERE 
                    RECORD_STATUS IN '||v_in_mode||' 
                AND 
                    RECORD_STATUS != ''''00''';
--EXECUTE DYNAMIC SQL AND HOLD VALUE IN l_exst      
    EXECUTE IMMEDIATE v_cnt_sql INTO l_exst;

    dbms_output.put_line(v_cnt_sql);    
    dbms_output.put_line(l_exst);

--IF MORE THAN 0 RECORDS EXIST
    IF
        l_exst>0
    THEN
        v_cnt:=v_cnt+1;
        v_dyn_sql:= 'UPDATE CONV_NL.'||v_in_skinny_table||'
                            SET BATCH='||v_cnt||' 
                            WHERE
                                RECORD_STATUS != ''''00''''
                            AND 
                                RECORD_STATUS IN '||v_in_mode||'
                            AND
                                ROWNUM < '||v_in_source_batch_size; --THIS IS THE VARIABLE BATCH SIZE OR NUMBER OF ROWS

        EXECUTE IMMEDIATE v_dyn_sql;
        COMMIT;
  END IF;
END LOOP;

有人可以指导我走向正确的方向。我希望我没有错过任何相关信息。

2 个答案:

答案 0 :(得分:2)

我最初对这个问题完全被误导了!

这......

SET BATCH = CEIL(ROWNUM/v_in_source_batch_size)

...刚刚足以一次更新所有内容?你需要 LOOPs (如果你最终可以COMMIT一切)

    v_dyn_sql:= 'UPDATE CONV_NL.'||v_in_skinny_table||'
                        SET BATCH=CEIL(ROWNUM/'||v_in_source_batch_size||') 
                        WHERE
                            RECORD_STATUS != ''''00''''
                        AND 
                            RECORD_STATUS IN '||v_in_mode; 

ROWNUM对应于它更新的行。 CEIL()向上舍入到最接近的整数:CEIL(1/10)仅给出1,所以也是......(2/10)...(10/10)。因此,CEIL(ROWNUM/10) ..前10行为1 ...接下来10行为2 ..等等10这里是Batchsize。

答案 1 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE Test (
  RECORD_STATUS VARCHAR2(4),
  ID            NUMBER(30),
  BATCH         NUMBER(1)
);

INSERT INTO Test
SELECT '''00''', LEVEL, NULL
FROM DUAL
CONNECT BY LEVEL <= 5;

INSERT INTO Test
SELECT 'AAA', LEVEL + 5, NULL
FROM DUAL
CONNECT BY LEVEL <= 4;

INSERT INTO Test
SELECT 'BBB', LEVEL +9, NULL
FROM DUAL
CONNECT BY LEVEL <= 7;

INSERT INTO Test
SELECT 'CCC', LEVEL +16, NULL
FROM DUAL
CONNECT BY LEVEL <= 6;

查询1

UPDATE TEST
SET    BATCH = CEIL( ROWNUM / 3 )
WHERE  RECORD_STATUS <> '''00'''

<强> Results

查询2

SELECT * FROM Test

<强> Results

| RECORD_STATUS | ID |  BATCH |
|---------------|----|--------|
|          '00' |  1 | (null) |
|          '00' |  2 | (null) |
|          '00' |  3 | (null) |
|          '00' |  4 | (null) |
|          '00' |  5 | (null) |
|           AAA |  6 |      1 |
|           AAA |  7 |      1 |
|           AAA |  8 |      1 |
|           AAA |  9 |      2 |
|           BBB | 10 |      2 |
|           BBB | 11 |      2 |
|           BBB | 12 |      3 |
|           BBB | 13 |      3 |
|           BBB | 14 |      3 |
|           BBB | 15 |      4 |
|           BBB | 16 |      4 |
|           CCC | 17 |      4 |
|           CCC | 18 |      5 |
|           CCC | 19 |      5 |
|           CCC | 20 |      5 |
|           CCC | 21 |      6 |
|           CCC | 22 |      6 |