[SQL] Substring + Charindex/Patindex

Substring + Charindex/Patindex [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 04-11-2010 à 16:04:24    

Bonjour,
 
Je galere un peu a extraire des propriétés d'un champ de texte en SQL Server (je sais :sarcastic: )
 
J'ai, dans un champ de texte, 3 propriétés que j'ai définies ainsi:
 
...
propriete1[5]
propriete2[56]
propriete3[3]
...
 
Maintenant j'aimerais acceder aux valeurs entre [ ] avec une requete. Le probleme, c'est que je connais pas la taille du contenu des [ ]. Ca peut etre a 1 ou 2 chiffres, voire 3. Bref, l'utilisation du Substring tombe a l'eau. En jonglant avec Charindex et Patindex, on peut facilement trouver le debut en filtrant sur propriete1, mais le probleme est de delimiter mon substring. Qqun a une idée ?
 
:jap:


---------------
Pier noir la mèr - La chanson par HFR Band - Topic TrueCrypt
Reply

Marsh Posté le 04-11-2010 à 16:04:24   

Reply

Marsh Posté le 05-11-2010 à 08:58:08    

Essaye ca:

Code :
  1. declare @tmpTable TABLE (ID int identity(1,1) PRIMARY KEY, Field1 varchar(50) NOT NULL)
  2.  
  3. INSERT @tmpTable (Field1) VALUES ('propriete1[5]'),
  4.                                  ('propriete2[56]'),
  5.                                  ('propriete3[3]')
  6.  
  7. SELECT *, SUBSTRING(Field1, CHARINDEX('[', Field1,1) + 1, CHARINDEX(']', Field1,1) - CHARINDEX('[', Field1,1) - 1) FROM @tmpTable

Reply

Marsh Posté le 05-11-2010 à 09:25:00    

Merci, mais je pense que je me suis mal exprimé. Tout ce que j'ai, c'est un varchar(2000) dans lequel il y a qqch du genre:
 

Citation :

blablabla blablaba blabl blabla blablabla blablaba blabl blabla blablabla blablaba blabl blabla
blablabla blablaba blabl blablablablabla blablaba blabl blabla
blablabla blablaba blabl blabla
propriete1[5]  
propriete2[56]  
propriete3[3]  
blablabla blablaba blabl blablablablabla blablaba blabl blabla
blablabla blablaba blabl blabla
blablabla blablaba blabl blablablablabla blablaba blabl blabla


 
et je veux extraire les 3 valeurs des propriétés. Je n'ai que des droits de lecture :jap:


---------------
Pier noir la mèr - La chanson par HFR Band - Topic TrueCrypt
Reply

Marsh Posté le 05-11-2010 à 14:05:07    

Ah, c'est un peu plus compliqué alors :)
 
Essaye ca:

Code :
  1. Declare @SQLStr varchar(2000)
  2.  
  3. SET @SQLStr = 'blablabla blablaba blabl blabla blablabla blablaba blabl blabla blablabla blablaba blabl blabla
  4. blablabla blablaba blabl blablablablabla blablaba blabl blabla
  5. blablabla blablaba blabl blabla
  6. propriete1[5]  
  7. propriete2[56]  
  8. propriete3[3]  
  9. blablabla blablab[115][12]a blabl blablablablabla blablaba blabl blabla
  10. blablabla blablaba blabl [21544]blabla
  11. blablabla blablaba blabl blablablablabla blablaba blabl blabla'
  12.  
  13. DECLARE @tmpTable TABLE (ID INT PRIMARY KEY, ValPropriete INT NULL, boundary INT NULL)
  14. DECLARE @LastBoundary int;
  15.  
  16. WITH cte10(n) AS (
  17.     SELECT 1 UNION ALL SELECT 1 UNION ALL
  18.     SELECT 1 UNION ALL SELECT 1 UNION ALL
  19.     SELECT 1 UNION ALL SELECT 1 UNION ALL
  20.     SELECT 1 UNION ALL SELECT 1 UNION ALL
  21.     SELECT 1 UNION ALL SELECT 1
  22. ), cte100(n) AS (SELECT 1 FROM cte10 a, cte10 b)
  23. INSERT @tmpTable (ID)
  24. SELECT ROW_NUMBER() OVER (ORDER BY n) n FROM cte100
  25.  
  26. SET @LastBoundary = 1
  27.  
  28. UPDATE @tmpTable
  29.     SET ValPropriete = CASE WHEN CHARINDEX('[',@SQLStr,@LastBoundary) = 0 THEN NULL ELSE SUBSTRING(@SQLStr, CHARINDEX('[',@SQLStr,@LastBoundary) + 1, CHARINDEX(']',@SQLStr,@LastBoundary + 1) - CHARINDEX('[',@SQLStr,@LastBoundary) - 1) END,
  30.     @LastBoundary = boundary = CASE WHEN CHARINDEX(']',@SQLStr,@LastBoundary + 1) = 0 THEN @LastBoundary WHEN ID = 1 THEN 1 ELSE CHARINDEX(']',@SQLStr,@LastBoundary + 1) + 1 END
  31.  
  32.  
  33. SELECT ValPropriete FROM @tmpTable WHERE ValPropriete IS NOT NULL ORDER BY ID


 
Il ne faut avoir rien d'autre que read pour faire tourner ca (ca n'utilise que des tables variable).
Je l'ai fait pour un max de 100 parametres mais ca peut tres facilement etre modifié pour tourner avec des millions de parametres si il faut.
 
Il faudra peut etre adapter un chouilla dans ton cas (ici j'ai fais un copié collé de la valeur dans une variable, mais tu peux tres bien faire un select pour l'avoir).
 
ps: Je peu expliquer le procédé en détail si il faut.


Message édité par Oliiii le 05-11-2010 à 14:09:44
Reply

Marsh Posté le 05-11-2010 à 14:25:32    

Alors la :D

 

Je vais tenter ca, pdt ce temps j'ai trouvé une demi solution (et dire que je la trouvais tordue avant de voir la tienne :D):

 
Code :
  1. substring(MonTexte,PATINDEX('%NumberOfItems[[]%', MonTexte)+14, CHARINDEX(']', MonTexte,CHARINDEX('NumberOfItems[', MonTexte,0))-CHARINDEX('NumberOfItems[', MonTexte,0)-14)
 

et cela 3 fois, pour mes 3 propriétés.

 

Le problème maintenant est que si le texte a chercher (MonTexte) ne contient PAS la propriété recherchée, il me dit que le 3eme parametre de Substring (donc la longueur) n'est pas valide (forcement, vu qu'il ne trouve pas de references). J'ai tenté de faire marcher le truc avec un ISNULL(), mais il ne veut pas :/

 


Merci pour ta réponse en tout cas :jap:


Message édité par ParadoX le 05-11-2010 à 14:58:06

---------------
Pier noir la mèr - La chanson par HFR Band - Topic TrueCrypt
Reply

Marsh Posté le 05-11-2010 à 15:20:22    

Trouvé [:volta]
 

Code :
  1. CASE
  2.     WHEN PATINDEX('%NumberOfItems[[]%', A_History) > 0
  3.     THEN substring(A_History,PATINDEX('%NumberOfItems[[]%', A_History) + 14, CHARINDEX(']', A_History,CHARINDEX('NumberOfItems[', A_History,0))-CHARINDEX('NumberOfItems[', A_History,0)-14)
  4.     ELSE 'N/A'
  5.     END
  6. as NumberOfItems,
  7. CASE
  8.     WHEN PATINDEX('%TypeOfItems[[]%', A_History) > 0
  9.     THEN substring(A_History,PATINDEX('%TypeOfItems[[]%', A_History) + 12, CHARINDEX(']', A_History,CHARINDEX('TypeOfItems[', A_History,0))-CHARINDEX('TypeOfItems[', A_History,0)-12)
  10.     ELSE 'N/A'
  11.     END
  12. as TypeOfItems,
  13. CASE
  14.     WHEN PATINDEX('%ReasonForDeletion[[]%', A_History) > 0
  15.     THEN  substring(A_History,PATINDEX('%ReasonForDeletion[[]%', A_History) + 18, CHARINDEX(']', A_History,CHARINDEX('ReasonForDeletion[', A_History,0))-CHARINDEX('ReasonForDeletion[', A_History,0)-18)
  16.     ELSE 'N/A'
  17.     END
  18. as ReasonForDeletion



Message édité par ParadoX le 05-11-2010 à 15:30:06

---------------
Pier noir la mèr - La chanson par HFR Band - Topic TrueCrypt
Reply

Marsh Posté le 05-11-2010 à 15:34:29    

Ma solution est pas tordue, elle est juste suffisement generique pour passer partout :)
 
Et peu fonctionner avec autant de parametres qu'on veut :)

Reply

Marsh Posté le 05-11-2010 à 16:32:00    

Merci pour ton aide en tout cas :jap:


---------------
Pier noir la mèr - La chanson par HFR Band - Topic TrueCrypt
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed