PostgreSQL Varchar UID到Int UID,同时保留唯一性
说我有一个独特的列VarChar(32)
。PostgreSQL Varchar UID到Int UID,同时保留唯一性
ex。 13bfa574e23848b68f1b7b5ff6d794e1
。
我想保留这个唯一性,同时将列转换为int
。我想我可以将所有的字母都转换成相应的ascii,同时保留数字和字符位置。为此,我将使用翻译功能。
伪代码:select translate(uid, '[^0-9]', ascii('[^0-9]'))
我的问题是找到所有的字母在VARCHAR列原本。 我试过
select uid, substring(uid from '[^0-9]') from test_table;
但它只返回它遇到的第一个字母。使用上面的例子,我会寻找bfaebfbbffde
任何帮助表示赞赏!
回答:
首先,我同意两位评论者说你应该使用UID数据类型。
这一边......
你的UID看起来像一个传统的,因为它不是字母数字,这是十六进制。如果是这样的话,你可以使用这个解决方案的十六进制转换为数值:
PostgreSQL: convert hex string of a very large number to a NUMERIC
通知接受的解决方案(我的,耻辱)是不如其他解决方案上市,作为煤矿将不适用于这个大的十六进制值。
这就是说,这是一个巨大的数字。圣烟。
取决于表中有多少条记录和插入/更新的频率,我会考虑一种截然不同的方法。简而言之,我会创建另一列来存储您的数字ID,其值将由序列确定。
如果你真的想让它刀枪不入,你也可以创建一个交叉引用表来存储将
- 重用一个ID,如果它曾经多次(我知道的UID没有关系,但这将涵盖记录被错误删除的情况下,再次出现,并且要保留原来的ID)
- 如果UID的重复(比如这是每个UID多个记录的子表),这将覆盖情况以及
如果没有这些应用,你ç应该把它弄歪了一下。
该解决方案将是这个样子:
添加一个ID列,这将是你的数字相当于UID:
alter table test_table add column id bigint
创建一个序列:
CREATE SEQUENCE test_id
创建交叉参考表(再次,对于虚拟版本不需要):
create table test_id_xref ( uid varchar(32) not null,
id bigint not null,
constraint test_id_xref_pk primary key (uid)
)
然后做一次更新替代ID分配给每个UID两种交叉引用和实际表:
insert into test_id_xref with uids as (
select distinct uid
from test_table
)
select uid, nextval ('test_id')
from uids;
update test_table tt
set id = x.id
from test_id_xref x
where tt.uid = x.uid;
最后,未来所有刀片,创建一个触发器来分配下一个值:
CREATE OR REPLACE FUNCTION test_table_insert_trigger() RETURNS trigger AS
$BODY$
BEGIN
select t.id
from test_id_xref t
into NEW.id
where t.uid = NEW.uid;
if NEW.id is null then
NEW.id := nextval('test_id');
insert into test_id_xref values (NEW.uid, NEW.id);
end if;
return NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE TRIGGER insert_test_table_trigger
BEFORE INSERT
ON test_table
FOR EACH ROW
EXECUTE PROCEDURE test_table_insert_trigger();
回答:
创建一个函数替换空白包车,你不是在串需要,
CREATE FUNCTION replace_char(v_string VARCHAR(32) CHARSET utf8) RETURNS VARCHAR(32) DETERMINISTIC
BEGIN
DECLARE v_return_string VARCHAR(32) DEFAULT '';
DECLARE v_remove_char VARCHAR(200) DEFAULT '1,2,3,4,5,6,7,8,9,0';
DECLARE v_length, j INT(3) DEFAULT 0;
SET v_length = LENGTH(v_string);
WHILE(j < v_length) DO
IF (FIND_IN_SET(SUBSTR(v_string, (j+1), 1), v_remove_char) = 0) THEN
SET v_return_string = CONCAT(v_return_string, SUBSTR(v_string, (j+1), 1));
END IF;
SET j = j+1;
END WHILE;
RETURN v_return_string;
END$$
DELIMITER ;
现在你只要东东调用这个函数在查询
select uid, replace_char(uid) from test_table;
它会给你字符串你需要(bfaebfbbffde
)
如果你只想int数,即13574238486817567941
那么改变变量的值和列数据类型在十进制(50,0)中,十进制可以存储大数,并且有小数点0,所以它将存储int值作为十进制。
v_remove_char = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z';
以上是 PostgreSQL Varchar UID到Int UID,同时保留唯一性 的全部内容, 来源链接: utcz.com/qa/259699.html