Pregunta

Estoy tratando de convertir una (50) de la columna varchar a un uniqueidentifier, pero este error sigue apareciendo todo el tiempo, y yo no sé por qué:

"Msg 8169, Level 16, State 2, Line 1 Conversion failed when converting from a character string to uniqueidentifier."

Los datos en la columna es actualmente un uniqueidentifier válido.

¿Cuál es la forma correcta de hacer lo que quiero?

Gracias

¿Fue útil?

Solución

¿Tiene alguna columnas que contienen cadenas vacías? Es decir. NO NULO, longitud de la cadena = 0.

O es que tiene alguna GUID con caracteres no estándar? Es decir. No 0-9, A-F?

Tenemos algunos GUID no estándar en mi solicitud que se crearon antes de que yo heredé ...

EDIT:

Para obtener ayuda futura, este script puede ayudar a encontrar las filas que no son válidos:

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')

Cualquier filas que tienen GUID no válidos se mostrarán, y se pueden encontrar por:

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'

Otros consejos

Sé que esto ya ha sido contestada, pero hay un enfoque un poco más elegante. Se puede utilizar el simplista, sintaxis exactamente-de un carácter comodín (es decir []) permitido en una cláusula LIKE para la prueba de dígitos hexadecimales válidos (es decir, 0 - 9 y a - F). Y, mediante el uso de una cláusula LIKE con la búsqueda de un solo carácter también se puede hacer cumplir el formato de un válido GUID / UNIQUEIDENTIFIER de una manera más fácil de leer a continuación el método REPLACE que tiene para normalizar primero todos los dígitos hexadecimales a 0 de antes de comparar con el formato válido .

CONFIGURACIÓN

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);

PRUEBAS

El siguiente ejemplo muestra utilizando 32 conjuntos de [0-9A-F] para cada posición hex dígitos del GUID y tiene la guiones (-) en los lugares apropiados. Tenga en cuenta:

  • la barra invertida (\) al final de cada línea en el patrón LIKE es la T-SQL Línea carácter de continuación , y
  • se debe utilizar una intercalación binaria para asegurar que los rangos de "0-9" y "A-F" no coincide con cualquier carácter que tienen valores en ese rango, pero no son específicamente dígitos decimales. Por ejemplo, el carácter superíndice "2" (²) no es un decimal 2, pero tiene un valor de 2 cuando se utiliza en un comodín gama y usando reglas de comparación Unicode (que se utilizan las reglas para todos los datos NVARCHAR y , incluso VARCHAR la colación es una intercalación de Windows - nombre de intercalación no a partir de SQL_). Prueba fila # 9 verifica este caso. Sin embargo, haciendo una comparación binaria requiere ya sea haciendo que la [0-9A-Fa-f] rango de patrones o envolver la columna en una función UPPER(). Utilice Latin1_General_100_BIN2 menos que esté utilizando SQL Server 2000 o 2005, en cuyo caso se debe utilizar 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;

Y, si bien esta pregunta se hizo en el contexto de SQL Server 2008, para cualquier persona que utiliza SQL Server 2012 o posterior, la TRY_CONVERT función hace aún más fácil:

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

Fuera de 5000 filas que tenían una que contiene un carácter no hexadecimal válido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top