Frage

Ich versuche, eine varchar (50) Spalte in eine Unique zu konvertieren, aber dieser Fehler hält die ganze Zeit auftauchen, und ich weiß nicht, warum:

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

Die Daten in der Spalte sind derzeit gültige eindeutige.

Was ist der richtige Weg zu tun, was ich will?

Danke

War es hilfreich?

Lösung

Haben Sie Spalten mit leeren Zeichenfolge? D. h NOT NULL, string length = 0.

Oder haben Sie GUIDs mit Nicht-Standard-Zeichen? D. h nicht 0-9, A-F?

Wir haben einige Nicht-Standard-GUIDs in meiner Anwendung, die erstellt wurden, bevor ich es geerbt ...

EDIT:

Für zukünftige Hilfe dieses Skript können Sie alle Zeilen finden, die nicht gültig sind:

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

Alle Zeilen, die ungültige Guids haben werden angezeigt und können durch gefunden werden:

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'

Andere Tipps

Ich weiß, dass dies bereits beantwortet worden, aber es ist ein etwas eleganter Ansatz. Sie können die vereinfachende, genau ein Zeichen-Platzhalter Syntax (dh []) in einer LIKE Klausel zulässig für gültige hexadezimale Ziffern zu testen (zB 0 - 9 und A - F). Und durch eine LIKE Klausel mit der Einzelzeichen Suche verwenden, können Sie auch das Format eines gültigen GUID / UNIQUEIDENTIFIER in eine besser lesbare Weise erzwingen dann die REPLACE Verfahren, das muss zuerst alle hexadezimalen Ziffern zu 0en normalisieren vor dem gültigen Format zu vergleichen .

EINRICHTUNG

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

TESTS

Das folgende Beispiel zeigt 32 Sätze von [0-9A-F] für jede hex-digit Position des GUID verwenden und hat die Striche (-) an den entsprechenden Stellen. Bitte beachten Sie:

  • der umgekehrte Schrägstrich (\) am Ende jeder Zeile in dem Muster ist die LIKE T-SQL-Zeilenfortsetzungszeichen und
  • sollten Sie eine binäre Sortierung verwenden, um sicherzustellen, dass Bereiche von „0-9“ und „A-F“ alle Zeichen nicht übereinstimmen, die Werte in diesem Bereich haben, sind aber nicht speziell Dezimalstellen. Zum Beispiel ist die obere Index „2“ Zeichen (²) keine dezimal 2, aber es hat einen Wert von 2, wenn sie in einem Bereich Platzhalter verwendet und mit Unicode-Vergleichsregeln (die die Regeln verwendet werden für alle NVARCHAR Daten und auch VARCHAR IF die Sortierung ist eine Windows-Sortierung - Kollatierungsnamen nicht mit SQL_ starten). Testzeile # 9 prüft diesen Fall. Jedoch erfordert einen binären Vergleich tun entweder den Bereich Muster [0-9A-Fa-f] machen oder die Spalte in einer UPPER() Funktion Verpackung. Verwenden Sie Latin1_General_100_BIN2 es sei denn, Sie verwenden SQL Server 2000 oder 2005, in diesem Fall sollten Sie Latin1_General_BIN verwenden.
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;

Und während diese Frage im Zusammenhang mit SQL Server 2008 gefragt wurde, für alle, die Verwendung von SQL Server 2012 oder höher, die TRY_CONVERT Funktion macht dies noch einfacher:

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

Von 5000 Zeilen hatte ich einen ein nicht hex-gültiges Zeichen enthält.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top