2010-05-04 9 views
7

Microsoft SQL Server 2008 (SP1), erhalten einen unerwarteten Fehler 'Konvertierung fehlgeschlagen'.Konvertierung fehlgeschlagen beim Konvertieren des Varchar-Werts in int

Nicht ganz sicher, wie dieses Problem zu beschreiben ist, so ist unten ein einfaches Beispiel. Der CTE extrahiert den numerischen Teil bestimmter IDs unter Verwendung einer Suchbedingung, um sicherzustellen, dass ein numerischer Teil tatsächlich existiert. Das CTE wird dann verwendet, um die niedrigste nicht verwendete Sequenznummer (Art) zu finden: ‚In dem Datentyp int‚

CREATE TABLE IDs (ID CHAR(3) NOT NULL UNIQUE); 

INSERT INTO IDs (ID) VALUES ('A01'), ('A02'), ('A04'), ('ERR'); 

WITH ValidIDs (ID, seq) 
AS 
(
SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
    FROM IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 
) 
SELECT MIN(V1.seq) + 1 AS next_seq 
    FROM ValidIDs AS V1 
WHERE NOT EXISTS (
        SELECT * 
        FROM ValidIDs AS V2 
        WHERE V2.seq = V1.seq + 1 
       ); 

Der Fehler ist,‘wenn die Fehler bei der Konvertierung VARCHAR-Wert-Umwandlungs‘ RR

Ich kann nicht verstehen, warum der Wert ID = 'ERR' für die Konvertierung berücksichtigt werden sollte, da das Prädikat ID LIKE 'A[0-9][0-9]' die ungültige Zeile aus der Ergebnismenge entfernt haben sollte.

Wenn die Basistabelle mit einer äquivalenten CTE das Problem verschwindet d.h.

substituiertes
WITH IDs (ID) 
AS 
(
SELECT 'A01' 
UNION ALL 
SELECT 'A02' 
UNION ALL 
SELECT 'A04' 
UNION ALL 
SELECT 'ERR' 
), 
ValidIDs (ID, seq) 
AS 
(
SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
    FROM IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 
) 
SELECT MIN(V1.seq) + 1 AS next_seq 
    FROM ValidIDs AS V1 
WHERE NOT EXISTS (
        SELECT * 
        FROM ValidIDs AS V2 
        WHERE V2.seq = V1.seq + 1 
       ); 

Warum eine Basistabelle diesen Fehler verursachen würde? Ist das ein bekanntes Problem?


@sgmoore UPDATE: Nein, in einem CTE das Filtern tun und das Gussteil in einem anderen CTE führt immer noch in dem gleichen Fehler z.B.

WITH FilteredIDs (ID) 
AS 
(
SELECT ID 
    FROM IDs 
    WHERE ID LIKE 'A[0-9][0-9]' 

), 
ValidIDs (ID, seq) 
AS 
(
SELECT ID, CAST(RIGHT(ID, 2) AS INTEGER) 
    FROM FilteredIDs 
) 
SELECT MIN(V1.seq) + 1 AS next_seq 
    FROM ValidIDs AS V1 
WHERE NOT EXISTS (
        SELECT * 
        FROM ValidIDs AS V2 
        WHERE V2.seq = V1.seq + 1 
       ); 
+1

Das Kern-CTE funktioniert gut - versuchen Sie es mit