SQL服务器2008转换VARCHAR(50)以唯一标识符
-
22-08-2019 - |
题
我想转换一个varchar(50)列的唯一标识符,但这个错误不断出现了所有的时间,我不知道为什么:
"Msg 8169, Level 16, State 2, Line 1 Conversion failed when converting from a character string to uniqueidentifier."
列数据目前是一个有效的唯一标识符.
有什么适当的方式做什么我想要什么?
感谢
解决方案
你有一个包含空字符串的列?即NOT NULL,串长度= 0。
或者你有非标字符的任何的GUID?即不0-9,A-F?
我们有进行之前,我继承了它创造了我的应用程序的一些不规范的GUID ...
编辑:
有关未来的帮助,这个脚本可以帮你找到无效的任何行:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(GUID, '1', '0'), '2', '0'), '3', '0'), '4', '0'), '5', '0'), '6', '0'), '7', '0'), '8', '0'), '9', '0'), 'A', '0'), 'B', '0'), 'C', '0'), 'D', '0'), 'E', '0'), 'F', '0'), COUNT(*)
FROM TABLE
GROUP BY REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(GUID, '1', '0'), '2', '0'), '3', '0'), '4', '0'), '5', '0'), '6', '0'), '7', '0'), '8', '0'), '9', '0'), 'A', '0'), 'B', '0'), 'C', '0'), 'D', '0'), 'E', '0'), 'F', '0')
具有无效的GUID任何行将显示出来,并且可被找到:
SELECT *, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(GUID, '1', '0'), '2', '0'), '3', '0'), '4', '0'), '5', '0'), '6', '0'), '7', '0'), '8', '0'), '9', '0'), 'A', '0'), 'B', '0'), 'C', '0'), 'D', '0'), 'E', '0'), 'F', '0')
FROM TABLE
WHERE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(GUID, '1', '0'), '2', '0'), '3', '0'), '4', '0'), '5', '0'), '6', '0'), '7', '0'), '8', '0'), '9', '0'), 'A', '0'), 'B', '0'), 'C', '0'), 'D', '0'), 'E', '0'), 'F', '0') != '00000000-0000-0000-0000-0000000000'
其他提示
我知道这已经回答了但有一个稍微更优雅的方法。你可以使用简单, 正是-一个字配符 语法(即 []
)允许在一个 LIKE
条款,以测试对于有效hex digits(即0-9和A-F)。而且,通过使用 LIKE
条款与单字的搜索,你也可以强制执行格式的一个有效的GUID/ UNIQUEIDENTIFIER
在一个更具可读性的方式,然后 REPLACE
方法有第一次的正常化的所有六位数到0的比较之前以有效的格式。
设置
SET NOCOUNT ON;
IF (OBJECT_ID('tempdb.dbo.#GUIDs') IS NOT NULL)
BEGIN
DROP TABLE #GUIDs;
END;
CREATE TABLE #GUIDs (ID INT NOT NULL, TheGUID VARCHAR(50) NULL);
INSERT INTO #GUIDs (ID, TheGUID)
SELECT tmp.ID, tmp.TheGUID
FROM (
SELECT 1, 'E1A21B62-ACC4-4ACB-B284-0F0233F19EDA' -- valid
UNION ALL
SELECT 2, '50178543-11E6-40D2-87F1-9C4676DCF542' -- valid
UNION ALL
SELECT 3, '' -- invalid: empty string
UNION ALL
SELECT 4, '4EB30267-0EB4-413A-9B05-6EDDB943C7D8' -- valid
UNION ALL
SELECT 5, '4EB30267-0EB4-413A-9Z05-6EDDB943C7D8' -- invalid: has a "Z"
UNION ALL
SELECT 6, NULL -- invalid: is NULL
UNION ALL
SELECT 7, '18EAE6C5-7256-4598-AA0A-837718145001' -- valid
UNION ALL
SELECT 8, '18eae6c5-7256-4598-aa0a-837718145001' -- valid (lowercase version of #7)
UNION ALL
SELECT 9, '18EAE6C5-7²56-4598-AA0A-837718145001' -- invalid: has superscript "2"
) tmp (ID, TheGUID);
测试
下面的示例说明了使用32套 [0-9A-F]
对于每一六位数字的位置GUID和具有破折号(-
)在适当的地方。请注意:
- 反斜杠(
\
)在每个月底线LIKE
图案的 T-SQL行继续符, , - 你应该使用的二进制序规则,以确保范围的"0-9"和"F"不符合任何人物,拥有数值在这一范围内,但不是具体的小数位数字。例如,标"2"字(
²
)是不是一个小数2,但它确实有价值的2时使用通配符的范围 和 使用Unicode比较的规则(该规则用于所有NVARCHAR
数据 和 甚至VARCHAR
如果 排序规则的一个窗户排序规则--的排序规则的名字 不 开始SQL_
).试行的第9验证这一情况。但是,这样做二进制的比较需要制的范围内模式[0-9A-Fa-f]
或者包裹列在UPPER()
功能。使用Latin1_General_100_BIN2
除非你使用的SQL Server2000年或2005年,在这种情况下则应使用Latin1_General_BIN
.
SELECT ID, TheGUID, CONVERT(UNIQUEIDENTIFIER, TheGUID) AS [Converted]
FROM #GUIDs
WHERE UPPER(TheGUID) COLLATE Latin1_General_100_BIN2 LIKE
'[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]\
[0-9A-F]';
SELECT ID, TheGUID AS [BAD]
FROM #GUIDs
WHERE UPPER(TheGUID) COLLATE Latin1_General_100_BIN2 NOT LIKE
'[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-\
[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]\
[0-9A-F]'
OR TheGUID IS NULL;
而且,虽然这个问题是问在上下文中SQL服务器2008年,对任何人使用SQL服务器2012年或更新的, TRY_CONVERT 功能,使这甚至更加容易:
SELECT tmp.ID, tmp.TheGUID AS [BAD]
FROM #GUIDs tmp
WHERE TRY_CONVERT(UNIQUEIDENTIFIER, tmp.[TheGUID]) IS NULL;
/*
ID BAD
3
5 4EB30267-0EB4-413A-9Z05-6EDDB943C7D8
6 (NULL)
9 18EAE6C5-7²56-4598-AA0A-837718145001
*/
在对5000行我有一个含有非己有效的字符。
不隶属于 StackOverflow