PLSQL:生成特定大小的下一个唯一键

时间:2013-11-12 10:54:51

标签: algorithm oracle plsql

我有一个表格,其中有一个名为 CODE 的主键 VARCHAR(3)。问题是000,001 .... 999中的所有可用值都用在不同的记录中。由于字段CODE是varchar格式,因此我们可以使用字母和数字。

plsql中是否有任何算法或函数可以通过它们统一生成长度为3的唯一键,其中包括字母表。请注意,我们无法更改字段大小,因为它在许多其他表中被引用。

2 个答案:

答案 0 :(得分:0)

您几乎肯定会将字段迁移到整数类型。如果这是不可能的,那么应该可以转换为更大的char字段,如bpgergo建议的那样。

如果你真的,真的坚持3个字符的限制,你可以使用to_char(id,'xxx')转换为十六进制,如:Oracle: How do I convert hex to decimal in Oracle SQL?

这将为您提供最多4096个条目。应该可以(但更复杂)使用base64(最多262,144个条目),或者达到128(2,097,152),或者只使用整个字段作为3字节无符号整数,如果你不关心原始的数据是可打印的字符(16,777,216)。

答案 1 :(得分:0)

这个解决方案怎么样? 基于oracle序列生成字母数字代码 请检查代码

declare
    l_val      number := 255; -- SQN_TMP_01.nextval;
    l_base     number := 62; -- 00azAZ
    l_base_str varchar2(62) := '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    l_res      number;
    l_final    varchar2(100);
begin
    loop
        -- init numberic value
        l_val   := SQN_TMP_01.nextval;
        l_final := null;
        dbms_output.put_line(l_val);

        -- convert value to alphanumeric code
        loop
            l_res   := mod(l_val, l_base);
            l_final := substr(l_base_str, l_res + 1, 1) || l_final;
            exit when l_val - l_res = 0;
            l_val := trunc((l_val - l_res) / l_base);
            dbms_output.put_line('res = ' || l_res || ' l_val = ' || l_val || ' final: "' || l_final || '"');
        end loop;

        dbms_output.put_line('check final: "' || l_final || '"');
        -- exclude full numeric result as already used
        exit when trim(translate(l_final, '0123456789', ' ')) is not null;
    end loop;
    dbms_output.put_line('final string: "' || l_final || '"');
end;