我想转换一个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行我有一个含有非己有效的字符。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top