2017-09-12 3 views
0

J'ai le code ci-dessous que je ne peux pas trouver ce qui cause l'erreur de conversion. Quelqu'un peut-il aider à identifier le problème?Erreur de conversion dans SQL Server - pourquoi?

[COLUMN_A] = CASE 
       WHEN [COLUMN_B] IS NOT NULL 
        AND [COLUMN_B] <> '' 
        AND CHARINDEX('MG', [COLUMN_B], 1) <> 0 
        THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT([COLUMN_B], CHARINDEX('MG', [COLUMN_B], 1))) 
       WHEN [COLUMN_B] IS NOT NULL 
        AND [COLUMN_B] <> '' 
        AND CHARINDEX('MCG', [COLUMN_B], 1) <> 0 
        THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT([COLUMN_B], CHARINDEX('MCG', [COLUMN_B], -1))) 
       WHEN [COLUMN_B] IS NOT NULL 
        AND [COLUMN_B] <> '' 
        THEN CONVERT(DECIMAL(8, 4), RTRIM([COLUMN_B])) 
       ELSE NULL 
    END 
+2

Quelle erreur obtenez-vous? – Xedni

+3

Veuillez fournir des exemples de données. Je devine que cela a à voir avec le fait que vous faites des suppositions sur ce à quoi ressemblent les chaînes et où vous pouvez réellement couper la chaîne pour obtenir un nombre décimal. – Xedni

+0

@Xedni - il n'y a * aucune donnée possible pouvant correspondre aux deux premières branches de l'expression de cas et être numérique. –

Répondre

1

Pour le cas où COLUMN_B contient la chaîne 'MCG' vous utilisez l'expression

LEFT([COLUMN_B], CHARINDEX('MCG', [COLUMN_B], -1)) 

Regardons ce qui renvoie des chaînes contenant cette sous-chaîne

+-----------+---------+ 
| COLUMN_B | Returns | 
+-----------+---------+ 
| MCG  | M  | 
| MCG 12.45 | M  | 
| 12.45 MCG | 12.45 M | 
+-----------+---------+ 

Vous pouvez donc voir que toute chaîne contenant MCG est garantie pour produire un résultat non numérique car ils contiennent tous la première lettre du sous-couplé chaîne. Donc, ceci est voué à ne pas être converti en décimal.

Cela n'a aucun sens de transmettre -1 comme troisième argument à CHARINDEX. C'est le start_location et une chaîne n'a pas de caractères négatifs.

Je suppose que vous essayez de trouver le charindex, puis soustrayez-en un pour extraire tout à gauche de la sous-chaîne sans inclure le M.

Vous avez donc besoin

LEFT([COLUMN_B], CHARINDEX('MCG', [COLUMN_B]) -1) 

Pour une valeur de COLUMN_B12.45 MCG ce sera de retour 12,45 and then your RTRIM` supprimera l'espace de fuite.

La même chose s'applique également à votre autre expression CHARINDEX.

Vous pouvez également supprimer les deux premières instances de [COLUMN_B] IS NOT NULL AND [COLUMN_B] <> '' - car si elle correspond au test charindex, elle ne sera pas vide et ne sera pas vide.

0
[COLUMN_A] = CASE 
      WHEN try_convert(nvarchar(max),[COLUMN_B]) IS NOT NULL 
       AND try_convert(nvarchar(max),[COLUMN_B]) <> '' 
       AND CHARINDEX('MG', try_convert(nvarchar(max),[COLUMN_B]), 1) <> 0 
       THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT(try_convert(nvarchar(max),[COLUMN_B]), CHARINDEX('MG', try_convert(nvarchar(max),[COLUMN_B]), 1))) 
      WHEN try_convert(nvarchar(max),[COLUMN_B]) IS NOT NULL 
       AND try_convert(nvarchar(max),[COLUMN_B]) <> '' 
       AND CHARINDEX('MCG', try_convert(nvarchar(max),[COLUMN_B]), 1) <> 0 
       THEN CONVERT(DECIMAL(8, 4), RTRIM(LEFT(try_convert(nvarchar(max),[COLUMN_B]), CHARINDEX('MCG', try_convert(nvarchar(max),[COLUMN_B]), -1))) 
      WHEN try_convert(nvarchar(max),[COLUMN_B]) IS NOT NULL 
       AND try_convert(nvarchar(max),[COLUMN_B]) <> '' 
       THEN CONVERT(DECIMAL(8, 4), RTRIM(try_convert(nvarchar(max),[COLUMN_B]))) 
      ELSE NULL 
END 

Cela devrait vous obtenir au moins l'erreur et de vous permettre d'obtenir au moins à courir à travers l'utilisation de la fonction de capture d'essai en ligne.