tsql, выбирая пары значений - PullRequest
       4

tsql, выбирая пары значений

1 голос
/ 01 сентября 2009

У меня есть столбец со следующими данными:

PersonId = "315618" LetterId = "43" MailingGroupId = "1" EntityId = "551723" trackedObjectId = "9538" EmailAddress = "myemailaddy@addy.com"

Есть ли хороший, чистый синтаксис tsql, чтобы получить 551723 (значение, связанное с EntityId). Комбинация Substring и Patindex, которую я использую, кажется довольно громоздкой.

Ответы [ 4 ]

3 голосов
/ 01 сентября 2009

Эта строка выглядит как список атрибутов XML для элемента, поэтому вы можете заключить ее в элемент XML и использовать xpath:

declare @t table (t nvarchar(max));
insert into @t (t) values (
    N'PersonId="315618" LetterId="43" MailingGroupId="1" 
     EntityId="551723" trackedObjectId="9538" 
     EmailAddress="myemailaddy@addy.com"');


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);

Лучше или хуже то, что манипулирование строками зависит от множества факторов, не в последнюю очередь от размера строки и количества анализируемых записей. Я предпочитаю простой и чистый синтаксис xpath над манипуляциями на основе индекса символов (код гораздо более удобен в обслуживании).

3 голосов
/ 01 сентября 2009

Если это текст в столбце, то на каком-то этапе вам придется использовать подстроку.

 declare @l_debug varchar(1000)
select @l_debug = 'PersonId="315618" LetterId="43" MailingGroupId="1" EntityId="551723" trackedObjectId="9538" EmailAddress="myemailaddy@addy.com"'

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

Если вы не знаете, насколько длинным может быть EntityID, вам нужно получить патекс следующей двойной кавычки после 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="myemailaddy@addy.com"'

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 голос
/ 01 сентября 2009

Если возможно, выложите свои данные. Либо нормализуйте свои таблицы, либо сохраните XML в столбце (с типом данных XML) вместо пар имя-значение. После этого вы сможете использовать полную мощность и скорость SQL Server или, по крайней мере, выполнять запросы XPath (при условии относительно недавней версии SQL Server).

Я знаю, что это, вероятно, не поможет вам в краткосрочной перспективе, но это цель, к которой нужно стремиться. :)

0 голосов
/ 01 сентября 2009
Substring(

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

)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...