2009-08-31 8 views
1

j'ai une colonne qui a les données suivantes:tsql, la cueillette des valeurs paires

personID = "315618" LetterId = "43" MailingGroupId = "1" entityID = "551723" trackedObjectId = "9538" EmailAddress = "[email protected]"

Existe-t-il une bonne syntaxe propre à tsql pour saisir le 551723 (la valeur associée à EntityId). La combinaison de Substring et Patindex que j'utilise semble assez compliquée.

Répondre

3

que les chaînes ressemble une liste d'attributs XML pour un élément, de sorte que vous pouvez l'envelopper dans un élément XML et utiliser XPath:

declare @t table (t nvarchar(max)); 
insert into @t (t) values (
    N'PersonId="315618" LetterId="43" MailingGroupId="1" 
    EntityId="551723" trackedObjectId="9538" 
    EmailAddress="[email protected]"'); 


with xte as (
    select cast(N'<x '+t+N'/>' as xml) as x from @t) 
select 
    n.value(N'@PersonId', N'int') as PersonId 
    , n.value(N'@LetterId', N'int') as LetterId 
    , n.value(N'@EntityId', N'int') as EntityId 
    , n.value(N'@EmailAddress', N'varchar(256)') as EmailAddress 
    from xte 
    cross apply x.nodes(N'/x') t(n); 

Que ce soit mieux ou pire que la chaîne la manipulation dépend de divers facteurs, notamment de la taille de la chaîne et du nombre d'enregistrements à analyser. Je préfère la syntaxe xpath simple et propre à la manipulation basée sur l'index char (le code est beaucoup plus facile à maintenir).

+0

Excellente idée Remus, je suis d'accord avec vous. – Daniel

3

Si c'est le texte dans la colonne, alors vous devrez utiliser la sous-chaîne à un certain stade.

declare @l_debug varchar(1000) 
select @l_debug = 'PersonId="315618" LetterId="43" MailingGroupId="1" EntityId="551723" trackedObjectId="9538" EmailAddress="[email protected]"' 

select substring(@l_debug, patindex('%EntityId="%', @l_debug)+ 10, 6) 

Si vous ne savez pas combien de temps EntityID pourrait être, alors vous aurez besoin pour obtenir le patindex du guillemet suivant après EntityID = »

declare @l_debug varchar(1000), @l_sub varchar(100), @l_index2 numeric 
select @l_debug = 'PersonId="315618" LetterId="43" MailingGroupId="1" EntityId="551723" trackedObjectId="9538" EmailAddress="myemailad[email protected]"' 

select @l_sub = substring(@l_debug, patindex('%EntityId="%', @l_debug)+ 10 /*length of "entityid=""*/, char_length(@l_debug)) 


select @l_index2 = patindex('%"%', @l_sub) 

select substring(@l_debug, patindex('%EntityId="%', @l_debug)+ 10, @l_index2 -1) 
1

Si vous le pouvez, Pour normaliser vos tables ou stocker du code XML dans la colonne (avec un type de données XML) au lieu des paires nom/valeur, vous pourrez utiliser toute la puissance et la vitesse de SQL Server, ou du moins capable d'émettre des requêtes XPath (en supposant une version relativement récente de SQL Server)

Je sais que cela ne vous aidera probablement pas à court terme, mais c'est un objectif à atteindre. :)

+0

Voilà comment je construis mes tables, mais malheureusement pas tout le monde le fait :) – Daniel

+0

Je me suis dit. Pardon! – TrueWill

+0

Je crois toujours que la refonte est la seule voie à suivre. Souhaitez-vous ne pas refactoriser le mauvais code dans l'application? C'est simplement une mauvaise conception et doit être refactorisé. – HLGEM

0
Substring(

Substring(EventArguments,PATINDEX('%EntityId%', EventArguments)+10,10),0, 
PATINDEX('%"%', Substring(EventArguments, 
PATINDEX('%EntityId%', EventArguments)+10,10)) 

) 
Questions connexes