Как создать возрастающую базовую буквенно-цифровую последовательность 62 в SQL Server

Я хотел бы создать увеличивающуюся буквенно-цифровую последовательность для таблицы сервера SQL, которая использует цифры 0-9, строчные буквы az и прописные буквы AZ. Таким образом, ряд будет выглядеть как 0, 1, 2, 3...9, a, b, c, d..., x, y, z, A, B, C, D...X, Y, Z и после этого он станет 11, 12, 13... 1a, 1b, 1c... 1X, 1Y, 1Z, затем 21, 22, 23... 2A, 2B и так далее.

Цель состоит в том, чтобы иметь инкрементный идентификатор строки, который является коротким в символах, по существу увеличиваясь, используя основную 62 буквенно-цифровую систему.

Мое первое желание состоит в том, чтобы создать таблицу со многими столбцами, и каждый столбец будет хранить место в системе. Итак, столбцы типа 0,0,0,0,0,1; и каждый раз, когда требуется новое значение, оно будет циклически проходить по столбцам, увеличиваясь по мере необходимости, в конечном итоге достигая значений, таких как 0,0,0,3,D,z и т. д.

У кого-нибудь есть более умная или краткая идея о том, как это сделать? Опять же, цель состоит в том, чтобы создать инкрементную последовательность, которая является "короткой" с точки зрения количества мест или символов, которые требуется для представления.

1 ответ

Благодарим @JohnCappelletti и Дэниела Баллинджера за ответ, найденный здесь: http://www.fishofprey.com/2011/08/convert-between-base-10-and-base-62-in.html

Задокументировать:

Преобразование из базы 10 в базу 62 в T-SQL

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Base62Encode](@a_number_to_convert [decimal](36, 0))
RETURNS [char](12) WITH EXECUTE AS CALLER
AS 
BEGIN

DECLARE @v_modulo INTEGER;  
DECLARE @v_temp_int decimal(38) = @a_number_to_convert;  
DECLARE @v_temp_val VARCHAR(256) = '';  
DECLARE @v_temp_char VARCHAR(1);    

--DECLARE @c_base62_digits VARCHAR(62) = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
DECLARE @c_base62_digits VARCHAR(62) = '0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'; 

 IF ( @a_number_to_convert = 0 )
 BEGIN
     SET @v_temp_val = '0';  
 END

 WHILE ( @v_temp_int <> 0 )
 BEGIN
     SET @v_modulo = @v_temp_int % 62;  
     SET @v_temp_char = substring( @c_base62_digits, @v_modulo + 1, 1 );  
     SET @v_temp_val = @v_temp_char + @v_temp_val;   
     SET @v_temp_int = floor(@v_temp_int / 62);  

 END

 RETURN @v_temp_val;  

END

Преобразование из базы 62 в базу 10 в T-SQL

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Base62Decode](@a_value_to_convert [char](12))
RETURNS [decimal](36, 0) WITH EXECUTE AS CALLER
AS 
BEGIN

DECLARE @v_iterator int;  
DECLARE @v_length int;  
DECLARE @v_temp_char VARCHAR(1);  
DECLARE @v_temp_int bigint;  
DECLARE @v_return_value decimal(38) = 0;  
DECLARE @v_multiplier decimal(38) = 1;  
DECLARE @v_temp_convert_val VARCHAR(256) = @a_value_to_convert;  

--DECLARE @c_base62_digits VARCHAR(62) = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
DECLARE @c_base62_digits VARCHAR(62) = '0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'; 


SET @v_length = len( @v_temp_convert_val );  
SET @v_iterator = @v_length; 

WHILE ( @v_iterator > 0 )   
BEGIN
    -- The character being converted
    SET @v_temp_char = substring( @v_temp_convert_val, @v_iterator, 1 );  
    -- The index of the character being converted
    SET @v_temp_int = charindex( @v_temp_char collate  SQL_Latin1_General_CP1_CS_AS, @c_base62_digits collate  SQL_Latin1_General_CP1_CS_AS ) - 1;  

    SET @v_return_value = @v_return_value + ( @v_temp_int * @v_multiplier );  
    SET @v_multiplier = @v_multiplier * 62;  
    SET @v_iterator = @v_iterator - 1;  

END

RETURN @v_return_value; 

END
Другие вопросы по тегам