2017-04-16 50 views
0

我有一个someTable的表,其中的类型为VARCHAR(4)。无论何时我插入此表,bin应该是字符和数字的唯一组合。这种意义上的独特含义在另一排中并未出现在表格中。在SQL中创建唯一的字符串/数字

bin的形式是AA00,其中A是字符A-F而0是数字0-9。

说我插入此表一次:它应该拿出一个bin价值,这在以前没有出现。假设表格是空的,第一个bin可能是AA11。在第二次插入,它应该是AA12,然后AA13

AA00, AA01, ... AA09, AA10, AA11, ... AA99, AB00, AB01, ... AF99, BA00, BA01, ... FF99

不要紧,这个表只能包含3600可能行。如何创建此代码,具体查找中尚不存在的bin?它可以按我所描述的顺序排列,也可以是随机的bin,只要它没有出现两次。

CREATE TABLE someTable (
    bin VARCHAR(4), 
    someText VARCHAR(32), 
    PRIMARY KEY(bin) 
); 

INSERT INTO someTable 
    VALUES('?', 'a'); 
INSERT INTO someTable 
    VALUES('?', 'b'); 
INSERT INTO someTable 
    VALUES('?', 'c'); 
INSERT INTO someTable 
    VALUES('?', 'd'); 

或者,我可以使用下面的步骤插入改为:

CREATE PROCEDURE insert_someTable(tsomeText VARCHAR(32)) 
    BEGIN 
    DECLARE var (VARCHAR(4) DEFAULT (
     -- some code to find unique bin 
    ); 
    INSERT INTO someTable 
     VALUES(var, tsomeText); 
    END 

一个可能的结果是:

+------+----------+ 
| bin | someText | 
+------+----------+ 
| AB31 | a  | 
| FC10 | b  | 
| BB22 | c  | 
| AF92 | d  | 
+------+----------+ 
+0

除非您决定在应用程序级别执行此操作,否则您需要触发器才能执行此操作。 –

回答

1

正如戈登说,你将不得不使用一个触发器,因为作为默认的简单公式太复杂了。应该相当简单,您只需获取最后一个值(按降序排列,限制为1)并增加它。由于字母字符,写入增量器会有点复杂。在应用程序语言中使用起来要容易得多,但后来遇到了表锁定问题以及两个用户创建相同值的可能性。

更好的方法是使用正常的自动增量主键并将其转换为二进制值。将您的bin值视为两个基本6个字符,然后是两个基本10个值。然后,您将由MySQL生成的id保证为唯一并转换为您的特殊号码系统。计算bin并将其存储在bin列中。

要计算斌:

  1. 步骤之一将是获得低100值十进制数(MOD 100) - ,让你的最后两位数字。使用前导零转换为varchar。
  2. 从id中减去该值,然后除以100得到前两位数的值。
  3. 获取mod 6值以确定第3个(从右侧)数字。按索引转换为A-F。
  4. 从ID剩下的内容中减去此值,然后除以6得到第4个(从右侧开始)数字。按索引转换为A-F。
  5. 将三个结果一起对准以形成箱的值。

您可能需要编辑以下内容以匹配您的表名和列名,但它应该如此您所要求的。一种可能的改进是取消任何超过3600限制的插入。如果插入第3600条记录,它将复制以前的箱值。此外,它不会插入AA00(id = 1 ='AA01'),所以它不完美。最后,你可以在bin上放置一个唯一索引,这样可以防止重复。

DELIMITER $$ 

CREATE TRIGGER `fix_bin` 
BEFORE INSERT ON `so_temp` 
FOR EACH ROW 
BEGIN 
    DECLARE next_id INT; 
    SET next_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='so_temp'); 
    SET @id = next_id; 
    SET @Part1 = MOD(@id,100); 
    SET @Temp1 = FLOOR((@id - @Part1)/100); 
    SET @Part2 = MOD(@Temp1,6); 
    SET @Temp2 = FLOOR((@Temp1 - @Part2)/6); 
    SET @Part3 = MOD(@Temp2,6); 

    SET @DIGIT12 = RIGHT(CONCAT("00",@Part1),2); 
    SET @DIGIT3 = SUBSTR("ABCDEF",@Part2 + 1,1); 
    SET @DIGIT4 = SUBSTR("ABCDEF",@Part3 + 1,1); 
    SET NEW.`bin` = CONCAT(@DIGIT4,@DIGIT3,@DIGIT12); 
END; 
$$ 

DELIMITER ; 
相关问题