Not sure if this approach will not lead to collisions (need to be examined from theoretic point of view), but I presume that probability of collision is still very low:
select utl_raw.bit_xor(utl_raw.substr(sys_guid(), 1, 8),
utl_raw.substr(sys_guid(), 9)) id
from dual
connect by level <= 10;
Another option is to use SEQUENCE
that minimum value is 1000000000000000
and cast it to character datatype.
What will be the main purpose of that ID
? Do you need to use it as primary key?
UPDATE:
After further consideration I recommend to stick with SEQUENCE
as it is native PK generation mechanism. If you need more than 10^16 - 10^15 - 1
unique values (that is the numbers from 1000000000000000 to 9999999999999999) then you can use hexadecimal representation. First, let's determine minimum and maximum numbers that fit 16 characters in hexadecimal form (assuming that there is no leading or trailing blanks):
select to_char(to_number('1000000000000000', 'XXXXXXXXXXXXXXXX')) min_value,
to_char(to_number('FFFFFFFFFFFFFFFF', 'XXXXXXXXXXXXXXXX')) max_value
from dual;
MIN_VALUE MAX_VALUE
--------------------------------------------
1152921504606846976 18446744073709551615
Now let's create SEQUENCE
using determined values:
create sequence my_sequence
minvalue 1152921504606846976
maxvalue 18446744073709551615
start with 1152921504606846976
increment by 1;
To generate primary key convert sequence number values to hexadecimal form:
select to_char(my_sequence.nextval, 'XXXXXXXXXXXXXXXX') hexadecimal_pk
from dual
connect by level <= 17;
HEXADECIMAL_PK
-----------------
1000000000000000
1000000000000001
1000000000000002
1000000000000003
1000000000000004
1000000000000005
1000000000000006
1000000000000007
1000000000000008
1000000000000009
100000000000000A
100000000000000B
100000000000000C
100000000000000D
100000000000000E
100000000000000F
1000000000000010
17 rows selected