문제

나는 Varchar (50) 열을 CirightIfnifier로 변환하려고하지만이 오류는 항상 계속 나타납니다. 왜 그런지 모르겠습니다.

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

열의 데이터는 현재 유효한 고유 한 식별자입니다.

내가 원하는 일을하는 올바른 방법은 무엇입니까?

감사

도움이 되었습니까?

해결책

빈 줄이 포함 된 열이 있습니까? 즉, 무효가 아니고 문자열 길이 = 0입니다.

아니면 비표준 문자가있는지도가 있습니까? 즉, 0-9, AF가 아닌가?

내 응용 프로그램에 비표준 가이드가 있습니다.

편집하다:

향후 도움을 위해이 스크립트는 유효하지 않은 행을 찾는 데 도움이 될 수 있습니다.

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

유효하지 않은 가이드가있는 모든 행은 나타나며 다음과 같이 찾을 수 있습니다.

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'

다른 팁

나는 이것이 이미 대답을 받았다는 것을 알고 있지만 약간 더 우아한 접근법이 있습니다. 단순한 것을 사용할 수 있습니다. 정확히 하나의 문자 와일드 카드 구문 (예 : []) 허용 a LIKE 유효한 16 진수 숫자를 테스트하는 조항 (예 : 0-9 및 A -F). 그리고 a LIKE 단일 문자 검색을 사용한 조항 유효한 안내서 형식을 시행 할 수도 있습니다. UNIQUEIDENTIFIER 보다 읽기 쉬운 방식으로 REPLACE 유효한 형식과 비교하기 전에 먼저 모든 16 진수를 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] 가이드의 각각 16 진수 위치에 대해 대시가 있습니다 (-) 적절한 장소에서. 참고 :

  • 백 슬래시 (\) 각 줄의 끝에서 LIKE 패턴은 T-SQL 라인 연속 문자, 그리고
  • "0-9"및 "af"범위가 해당 범위에 값이 있지만 구체적으로 소수점 자릿수가 아닌 문자와 일치하지 않도록 바이너리 콜레이션을 사용해야합니다. 예를 들어, 슈퍼 스크립트 "2"문자 (²) 소수점 2는 아니지만 범위 와일드 카드에 사용될 때 값이 2입니다. 그리고 유니 코드 비교 규칙 사용 (모두에 사용되는 규칙입니다. NVARCHAR 데이터 그리고 조차 VARCHAR 만약에 Collation은 Windows Collation - Collation 이름입니다 ~ 아니다 로 시작 SQL_). 테스트 행 #9는이 경우를 확인합니다. 그러나 이진 비교를 수행하려면 범위 패턴을 만들려면 [0-9A-Fa-f] 또는 열을 안에 감싸는 것 UPPER() 기능. 사용 Latin1_General_100_BIN2 SQL Server 2000 또는 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 Server 2008의 맥락에서 요청되었지만 SQL Server 2012 또는 Newer를 사용하는 사람은 누구나 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