Проблема SQL-запроса в SQL Server 2008 - PullRequest
0 голосов
/ 14 июля 2010

Я использую SQL Server 2008 Enterprise + VSTS 2008 + C # + .Net 3.5 + ASP.Net + IIS 7.0 для разработки простого веб-приложения.В моей таблице базы данных у меня есть столбец типа XML.Содержимое, как показано ниже,

Я хочу получить AdditionalInfoList всех строк в таблице, если в заголовке содержится «инженер-программист» или в Info содержится «разработка программного обеспечения».У меня вопрос, как эффективно написать такой запрос?

<People>
  <Item Name="Username" Value="George" />
  <Item Name="Info" Value="Software Development Information" />
  <Item Name="Title" Value="Software Engineer in Backend" />
  <AdditionalInfoList>
    <AdditionalInfoListItem Guid="xxx" type="type1" />
    <AdditionalInfoListItem Guid="yyy" type="type2" />
  </AdditionalInfoList>
</People>

1 Ответ

2 голосов
/ 14 июля 2010

Вам нужно сделать что-то вроде этого:

SELECT
    t.ID, -- or whatever you need from the table where the XML is located
    tbl.People.query('AdditionalInfoList')
FROM
    dbo.YourTable  t
CROSS APPLY
    t.(xmlcolumn).nodes('/People') AS Tbl(People)
WHERE
    tbl.People.value('(Item[@Name="Info"]/@Value)[1]', 'varchar(50)') LIKE '%Software Development%'
    OR
    tbl.People.value('(Item[@Name="Title"]/@Value)[1]', 'varchar(50)') LIKE '%Software Engineer%'

Это должно дать вам все интересующие вас записи.

Пояснения

CROSS APPLY создает "фиктивную" таблицу, которой вам нужно дать имя - здесь: Tbl(People). Что это имя на самом деле не имеет значения, и оно не учитывает регистр, поэтому Tbl и tbl идентичны.

Если вы хотите, чтобы Guid и тип были отдельными значениями от <AdditionalInfoList>, вам нужно использовать этот запрос здесь:

SELECT
    t.ID,
    --tbl.People.value('(Item[@Name="Info"]/@Value)[1]', 'varchar(50)') AS 'Info',
    --tbl.People.value('(Item[@Name="Title"]/@Value)[1]', 'varchar(50)') AS 'Title'
    Adtl.Info.value('(@Guid)[1]', 'varchar(50)') AS 'GUID',
    Adtl.Info.value('(@type)[1]', 'varchar(50)') AS 'Type'
FROM
    @table t
CROSS APPLY 
    t.xmlcolumn.nodes('/People') AS Tbl(People)
CROSS APPLY 
    Tbl.People.nodes('AdditionalInfoList/AdditionalInfoListItem') AS Adtl(Info)
WHERE
    Tbl.People.value('(Item[@Name="Info"]/@Value)[1]', 'varchar(50)') LIKE '%Software Development%'
    OR
    Tbl.People.value('(Item[@Name="Title"]/@Value)[1]', 'varchar(50)') LIKE '%Software Engineer%'

В основном вам нужно выполнить второе ПРИМЕНЕНИЕ КРОССА (что ухудшит вашу производительность!), Чтобы получить список «дополнительной информации» для каждой записи из Tbl.Person и извлечь из него Guid и значение типа.

Ознакомьтесь с введением SQL Server 2005 XQuery и XML DML - примерно в середине статьи есть раздел о том, как использовать функцию .nodes(). Очень полезно!

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