2017-09-15 4 views
1

J'ai été occupé pendant 2 jours pour trouver une solution à mon problème. J'ai une grande base de données et je veux remplacer un ensemble de nombres dans une colonne.SQL Remplacer la longueur fixe, différentes valeurs numériques dans la colonne TEXT

La colonne contient du texte et dans ce texte il a ce format FPC1234567890. La seule chose est: les chiffres sont toujours différents (mais toujours 10 de longueur), les 3 lettres sont toujours les mêmes.

J'ai essayé ceci:

update [tablename] 
SET columnname = 
    CAST(REPLACE(CAST(columnname as NVarchar(4000)), 
    'FPC[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]', 'newclientnumber') AS NText) 

Cela ne fonctionne pas, comme les jokers ne fonctionnent pas avec la fonction de remplacement, il ne fonctionne pas quand je tape dans l'un des numéros corrects résidant dans la colonne.

je peux trouver ce que je dois mettre à jour avec ceci:

SELECT * FROM Tablename 
WHERE columnname LIKE '%FPC[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%' 
+1

Marquez les dbms que vous utilisez. (sql-server peut-être?) – jarlh

Répondre

0

SQL Server a une fonction PATINDEX qui ressemble à un modèle donné similaire à LIKE. Si votre text colonne ne peut contenir qu'une seule instance de ce modèle (non multiple), alors vous pouvez le faire comme ceci:

WITH 
CTE 
AS 
(
SELECT 
    columnname 
    ,new_value 
FROM 
    Tablename 
    CROSS APPLY 
    (
     SELECT 
      CAST(columnname as nvarchar(max)) AS columnname_nvarchar 
    ) AS CA1 
    CROSS APPLY 
    (
     SELECT 
      PATINDEX('%FPC[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', 
       columnname_nvarchar) AS idx 
    ) AS CA2 
    CROSS APPLY 
    (
     SELECT 
      CAST(
       LEFT(columnname_nvarchar, idx) + 
       'newclientnumber' + 
       RIGHT(columnname_nvarchar, LEN(columnname_nvarchar) - idx - 13) 
      AS ntext) AS new_value 
    ) AS CA3 
WHERE columnname LIKE '%FPC[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%' 
) 
--SELECT * FROM CTE; 
--UPDATE CTE SET columnname = new_value; 

I utilisé CTE et CROSS APPLY pour rendre la requête plus lisible et éviter de répéter les expressions. Vous pouvez mettre toutes ces expressions en UPDATE simple.

Je recommande d'exécuter d'abord la requête avec la ligne SELECT * FROM CTE; non commentée pour vérifier que le résultat est correct. Vous devrez probablement ajuster la formule, ajouter ou soustraire 1 à quelques endroits. Une fois que vous confirmez que les calculs sont corrects, commentez SELECT et décommentez la ligne UPDATE.


Si vos valeurs de texte peuvent contenir plusieurs cas de ce modèle, vous pouvez exécuter les UPDATE ci-dessus plusieurs fois jusqu'à ce que les valeurs cessent de changer (nombre de lignes affectées deviennent zéro).

+0

MERCI Vladimir! Juste pour que je comprenne, que fait le '- 13'? (RIGHT (nom_colonne_nvarchar, LEN (nom_colonne_nvarchar) - idx-13) – user1654659

+0

@ utilisateur1654659, '13' correspond à la longueur de la chaîne que vous remplacez (' FPC1234567890'). Essayez d'exécuter la requête et vérifiez le résultat. pour ajuster ce nombre de +1 ou -1. –