我有一个表,其中有一个名为CODE类型的主键VARCHAR(3)。问题是 000,001 .... 999 中的所有可用值都用于不同的记录。由于字段 CODE 是 varchar 格式,所以我们可以有字母和数字。
plsql 中是否有任何算法或函数,通过它我们可以统一生成长度为 3 的唯一键,其中也包括字母表。请注意,我们无法更改字段大小,因为它在许多其他表中被引用。
您几乎可以肯定将您的字段迁移到整数类型。如果这是不可能的,那么应该可以按照 bpgergo 的建议转换为更大的 char 字段。
如果您真的非常受 3 个字符的限制,您可以使用 to_char(id, 'xxx') 转换为十六进制,如:Oracle:如何在 Oracle SQL 中将十六进制转换为十进制?
这将为您提供多达 4096 个条目。应该可以(但更复杂)使用 base64(最多 262,144 个条目),或者到基数 128(2,097,152),或者如果您不关心原始数据,则只需将整个字段用作 3 字节无符号整数数据是可打印的字符 (16,777,216)。
这个解决方案如何根据 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;