Sql server SQL Server 2008将VARCHAR(50)转换为Uniqueidentifier

Sql server SQL Server 2008将VARCHAR(50)转换为Uniqueidentifier,sql-server,tsql,sql-server-2008,type-conversion,uniqueidentifier,Sql Server,Tsql,Sql Server 2008,Type Conversion,Uniqueidentifier,我正在尝试将varchar50列转换为uniqueidentifier,但此错误一直出现,我不知道原因: "Msg 8169, Level 16, State 2, Line 1 Conversion failed when converting from a character string to uniqueidentifier." 列中的数据当前是有效的唯一标识符 做我想做的事的正确方法是什么 谢谢您有包含空字符串的列吗?即不为空,字符串长度=0 或者你有没有非标准字符的guid?也就是

我正在尝试将varchar50列转换为uniqueidentifier,但此错误一直出现,我不知道原因:

"Msg 8169, Level 16, State 2, Line 1 Conversion failed when converting from a character string to uniqueidentifier."
列中的数据当前是有效的唯一标识符

做我想做的事的正确方法是什么


谢谢

您有包含空字符串的列吗?即不为空,字符串长度=0

或者你有没有非标准字符的guid?也就是说,不是0-9,A-F

我们在我的应用程序中有一些非标准的GUI,它们是在我继承它之前创建的

编辑:

对于将来的帮助,此脚本可以帮助您查找任何无效行:

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'

在5000行中,我有一行包含非十六进制有效字符。

我知道这已经得到了回答,但有一种更优雅的方法。您可以使用LIKE子句中允许的简单语法,即【】,来测试有效的十六进制数字,即0-9和a-F。并且,通过在单字符搜索中使用LIKE子句,您还可以以比替换方法更可读的方式强制执行有效GUID/UNIQUEIDENTIFIER的格式,替换方法必须首先将所有十六进制数字标准化为0,然后再与有效格式进行比较

设置

测验

下面的示例显示了对GUID的每个十六进制数字位置使用32组[0-9A-F],并且在适当的位置有破折号。请注意:

LIKE模式中每行末尾的反斜杠\为,和 您应该使用二进制排序规则来确保0-9和a-F的范围不匹配任何在该范围内有值但不是特定十进制数字的字符。例如,上标2字符²不是十进制2,但当在范围通配符中使用并且使用Unicode比较规则(用于所有NVARCHAR数据甚至VARCHAR的规则,如果排序规则是Windows排序规则-排序规则名称不以SQL开头)时,它的值为2。测试行9验证这种情况。但是,进行二进制比较需要创建范围模式[0-9A-Fa-f]或将列包装到上限函数中。除非您使用的是SQL Server 2000或2005,否则请使用Latin1_General_100_BIN2,在这种情况下,您应该使用Latin1_General_BIN。 选择ID、GUID、CONVERTUNIQUEIDENTIFIER、GUID为[Converted] 来自GUIDs 上面的GUID与拉丁文1\u General\u 100\u BIN2类似 “[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]'; 选择ID,GUID为[BAD] 来自GUIDs 上面的GUID比较拉丁语1\u General\u 100\u BIN2不一样 “[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]' 或者GUID为空; 而且,虽然在SQL Server 2008的上下文中提出了这个问题,但对于任何使用SQL Server 2012或更新版本的人来说,该函数使这一问题变得更加简单:

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
*/

请问您要转换的字符串是什么?
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
*/