使用计数器更新现有数据的数据库列

updating a column of database with existing data with a counter

我有一个带有 table 的 oracle 数据库,其中包含现有数据。 我想添加一个字段并使用从 0001 开始的计数器更新它,它将像 0010,0011 ... 0100 一样继续到现有数据。

有办法实现吗?

使用BITAND函数 它给出了下一个结果:

SELECT BITAND(128, 128) FROM DUAL; --> 128

如果你把

SELECT BITAND(127, 128) FROM DUAL; --> 0

如果你把

SELECT BITAND(255, 128) FROM DUAL; --> 128

所以规则是:

SELECT BITAND(M, N) FROM DUAL; IF M < N OR M >= 2*N --> 0

因此,要获取您的号码,您可以使用此方法:

SELECT 
  DECODE(BITAND(my_value, 128), 128, '1', '0') ||
  DECODE(BITAND(my_value, 64), 64, '1', '0') ||
  DECODE(BITAND(my_value, 32), 32, '1', '0') ||
  DECODE(BITAND(my_value, 16), 16, '1', '0') ||
  DECODE(BITAND(my_value, 8), 8, '1', '0') ||
  DECODE(BITAND(my_value, 4), 4, '1', '0') ||
  DECODE(BITAND(my_value, 2), 2, '1', '0') ||
  DECODE(BITAND(my_value, 1), 1, '1', '0') as binary_number FROM
(SELECT <put_any_number> as my_value FROM DUAL) A;

从这里开始,您必须在 INTO 语句中使用 VARCHAR2 变量。

根据您的描述,这可能是一种选择:

样本table:

SQL> create table test as select * from dept;

Table created.

添加 counter 列:

SQL> alter table test add counter varchar2(4);

Table altered.

更新一下:

SQL> update test set counter = lpad(rownum, 4, '0');

4 rows updated.

结果:

SQL> select * From test;

    DEPTNO DNAME          LOC           COUN
---------- -------------- ------------- ----
        10 ACCOUNTING     NEW YORK      0001
        20 RESEARCH       DALLAS        0002
        30 SALES          CHICAGO       0003
        40 OPERATIONS     BOSTON        0004

SQL>

如果计数器实际上是二进制表示,那么您可能会使用这样的东西:

SQL> alter table test add counter_binary varchar2(4);

Table altered.

SQL> merge into test t
  2    using(with temp as
  3            (select deptno, row_number() over (order by deptno) rn
  4             from test
  5            )
  6          select deptno,
  7            lpad(listagg(sign(bitand(rn, power(2, column_value - 1))), '')
  8            within group (order by column_value desc), 4, '0') bin
  9          from temp cross join
 10            table(cast(multiset(select level from dual
 11                                connect by power(2, level - 1) <= rn
 12                               ) as sys.odcinumberlist))
 13          group by deptno) x
 14    on (t.deptno = x.deptno)
 15    when matched then update set t.counter_binary = x.bin;

4 rows merged.

SQL> select * from test;

    DEPTNO DNAME          LOC           COUNTER    COUNTER_BINARY
---------- -------------- ------------- ---------- ---------------
        10 ACCOUNTING     NEW YORK      0001       0001
        20 RESEARCH       DALLAS        0002       0010
        30 SALES          CHICAGO       0003       0011
        40 OPERATIONS     BOSTON        0004       0100

SQL>