我需要使用 MSSQL 從給定的字串創建永久 GUID/UUID,但沒有找到解決方案。因此,每次呼叫函式時,字串“A12345”都會變成類似于“AAAAAAAA-1234-5678-90AB-AAAAAAAAAAA”的東西。需要一些建議或示例來實作這一目標。
uj5u.com熱心網友回復:
正如評論中所說的那樣,您可能應該重新考慮,但是.. 如果字串是型別varchar(16)或更小(不是 nvarchar),那么有一種方法可以至少大致實作我理解您的目標。
我對您的案例了解得不夠多,無法推薦此解決方案,但假設您確實需要這樣做。如果沒有別的,這可能會幫助您構建自己的功能,或者認為這是一個壞主意。如果您想要回傳原始值,則下面的解決方案要求您構建另一個函式,以便在檢索資料時基本上反向執行相同的操作。
唯一識別符號由 0-9 和 AF 之間的 32 個字母數字字符組成的字串以及四個短劃線直觀地表示。這意味著您在該字串中的每個位置有 16 個選項,共有 32 個位置。我建議不要在這個函式中使用字母 A 作為填充符,下面我使用 0 代替,因為 00 在 ASCII 中是NULL,而 AA 將代表一個實際字符。
首先,您可以使用該函式將字串中的每個字符轉換為其 ASCII 值ASCII()。此后,您可以通過對該值使用除法和模 16 將回傳的整數轉換為十六進制字串表示形式。SQL Server 中的 ASCII 范圍為 0-255,這意味著有 256 個不同的字符。256 是 16 乘以 16,這意味著您需要 uniqueidentifier 中的兩個位置來表示輸入字串中的每個字符,因此此函式中的最大字串限制為 16 個而不是 32 個(請參閱前面的段落)。最后,您需要在正確的位置插入破折號并將字串轉換為唯一識別符號。
CREATE FUNCTION dbo.MYGUID (@input varchar(17))
RETURNS uniqueidentifier
BEGIN
/* Unable to convert any string langer than 16 characters with this method */
IF LEN(@input) > 16
RETURN CAST('FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF' as uniqueidentifier)
DECLARE
@result varchar(36) = '',
@char char(1) = '',
@placeholder varchar(32) = REPLICATE('0',32)
/* Convert all characters in string to psuedo-hexadecimal */
WHILE LEN(@input) > 0 BEGIN
/* Use first character in input string.. */
SET @char = LEFT(@input, 1)
/* Convert character to hexadecimal representation */
SET @result = CONVERT(char(1),
CASE ASCII(@char) / 16
WHEN 10 THEN 'A'
WHEN 11 THEN 'B'
WHEN 12 THEN 'C'
WHEN 13 THEN 'D'
WHEN 14 THEN 'E'
WHEN 15 THEN 'F'
ELSE CONVERT(char, ASCII(@char) / 16)
END)
CONVERT(char(1),
CASE ASCII(@char) % 16
WHEN 10 THEN 'A'
WHEN 11 THEN 'B'
WHEN 12 THEN 'C'
WHEN 13 THEN 'D'
WHEN 14 THEN 'E'
WHEN 15 THEN 'F'
ELSE CONVERT(char, ASCII(@char) % 16)
END
)
/* Remove first character from input string.. */
SET @input = STUFF(@input, 1, 1, '')
END
/* Make sure there are exactly 32 alpha-numeric characters in outgoing string */
SET @result = RIGHT(@placeholder @result,32)
/* Insert dashes at the correct positions */
SET @result = STUFF(@result, 21, 0, '-')
SET @result = STUFF(@result, 17, 0, '-')
SET @result = STUFF(@result, 13, 0, '-')
SET @result = STUFF(@result, 9, 0, '-')
/* Returns string as uniqueidentifier */
RETURN CAST(@result as uniqueidentifier)
END
創建函式后,您可以使用它...
SELECT dbo.MYGUID(column1)
FROM table1
..或者..
SELECT dbo.MYGUID('A12345')
uj5u.com熱心網友回復:
如果您只是想創建一個映射,您可以執行以下操作(例如 fiddle):
創建一個表來保存映射
create table StringGuidMap (
Guid uniqueidentifier not null constraint PK_StringGuidMap primary key clustered default NewSequentialId()
, StringId nvarchar(8) not null constraint UK_StringGuidMap_StringId unique
)
創建邏輯以獲取映射或根據需要創建新映射:
create procedure sp_GetIdMapping (
@StringId nvarchar(8)
) as
begin
declare @result uniqueidentifier = null
select @result = Guid
from StringGuidMap
where StringId = @StringId -- note: case/accent sensitivity depends on your DB's collation
if (@result is null)
begin
insert into StringGuidMap(StringId)
values (@StringId)
select @result = Guid
from StringGuidMap
where StringId = @StringId
end
select @result Guid
end
在上面我使用NewSequentialId了 GUID 生成,確保該列可以很容易地用作索引中的主鍵/而不會導致碎片,因為生成的每個新 ID 都將放在現有索引的末尾。但是,newid()如果您愿意/可以在存盤程序中生成 GUID 而不是作為插入中的默認值,則可以使用生成 GUID,從而減少那里的呼叫。你去哪取決于你的要求
注:以上為映射;但是這種映射只對有映射表的人有意義/這不是普遍正確的;同樣,這是否合適取決于您的要求。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/485774.html
上一篇:將數字和小數轉換為INT
