在oracle中使用序列更新分组记录

时间:2014-11-20 18:26:07

标签: sql oracle

我在Oracle表中有以下数据结构

COL1    COL2    COL2   GRP_ID
A       A       B      1
A       A       B      1
A       A       C      2
A       A       B      1
A       D       E      3
A       D       E      3
F       G       H      4
F       G       H      4

基本上,col1,col2和col3的每个唯一组合在GRP_ID列中具有不同的值。

我需要将GRP_ID列中的值替换为数据库序列值,以便(假设序列的下一个值为235678):

COL1    COL2    COL2   GRP_ID
A       A       B      235678
A       A       B      235678
A       A       C      235679
A       A       B      235678
A       D       E      235680
A       D       E      235680
F       G       H      235681
F       G       H      235681     

表中有数百万条记录,所以我不想经历一个循环。使用数据库序列的原因是序列提供的数字将暴露给客户,因此在下次通信发送给客户时不应重复。

有没有办法通过SQL做到这一点?

谢谢!

2 个答案:

答案 0 :(得分:1)

不知道是否是最快的方式,但它有效。

CREATE FUNCTION NEXT
      RETURN NUMBER IS
      v_nextval NUMBER;
    BEGIN
      v_nextval := NEW_SEQUENCE.nextval;

      RETURN(v_nextval);
   END;
/

UPDATE EXAMPLE
SET EXAMPLE.GroupID = 
  (  
   SELECT G.GroupID FROM 
   ( 
     SELECT B.Column1, B.Column2, B.Column3, MY_SCHEMA.NEXT() AS GroupID 
     FROM EXAMPLE B 
     GROUP BY B.Column1, B.Column2, B.Column3
   ) G 
   Where G.Column1 = EXAMPLE.Column1 AND G.Column2 = EXAMPLE.Column2 
   AND G.Column3 = EXAMPLE.Column3);

SELECT * 
FROM EXAMPLE

基本上你必须做一个distinct或group by来获取你拥有的所有不同的组并在函数中使用序列,否则你将得到序列号,这里不允许来自oracle的错误,然后进行更新。< / p>

请参阅sqlfiddle上的完整示例

http://sqlfiddle.com/#!4/bf261/8

答案 1 :(得分:0)

怎么样:

  1. 开始交易
  2. 获取temp var中的下一个序列
  3. 禁用顺序
  4. update tablename set grp_ID = grp_ID + tmpVar-1
  5. Select into tempVar max(grp_ID) from tableName
  6. 现在在tempvar + 1
  7. 中重新基于序列的值
  8. 重新启用序列
  9. 提交和结束交易
  10. 但是当我稍后添加其他记录时我感到困惑,他们不能简单地执行sequence.nextval,因为只有在col1,col2,col3还没有时才需要它存在,否则它应该使用group_ID为那个独特的组合...只是看起来很奇怪,可行但奇怪。