【发布时间】:2021-08-14 09:00:03
【问题描述】:
我有一个包含现有数据的表的 oracle 数据库。 我想添加一个字段并使用从 0001 开始的计数器更新它,该计数器将继续像 0010,0011 ... 0100 等现有数据。
有没有办法做到这一点?
【问题讨论】:
-
这些计数器值是否代表二进制值?
-
为什么不直接使用整数?
标签: sql oracle sql-update
我有一个包含现有数据的表的 oracle 数据库。 我想添加一个字段并使用从 0001 开始的计数器更新它,该计数器将继续像 0010,0011 ... 0100 等现有数据。
有没有办法做到这一点?
【问题讨论】:
标签: sql oracle sql-update
按照你描述的方式,这可能是一种选择:
示例表:
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>
【讨论】:
row_number() over (order by deptno)
使用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 变量。
【讨论】: