Фильтр XQuery как предложение Where - PullRequest
3 голосов
/ 08 июля 2011

Я получил данные на основе определенного условия из значения XML. Идея состоит в том, чтобы иметь одну таблицу с двумя столбцами ID и Data (XML dataType). Я должен получить данные для конкретного идентификатора.

Вот пример, и я хочу достичь результата только в первой строке только с Sears Tower. Я получаю два ряда.

IF OBJECT_ID('tempdb..#ExistExample') IS NOT NULL
DROP TABLE #ExistExample
GO

CREATE TABLE #ExistExample
(
  XMLID Int,
  XMLDocument xml
)

INSERT INTO #ExistExample
VALUES (100,'<Buildings>
  <Building>
    <Name>Sears Tower</Name>
    <Floor1>Yes</Floor1>
    <Floor2>Yes</Floor2>
    <Floor3>No</Floor3>
  </Building>
  <Building>
    <Name>IDS Building</Name>
      <Floor1>Yes</Floor1>
      <Floor2>Yes</Floor2>
      <Floor3>Yes</Floor3>
  </Building>
</Buildings>')

DECLARE @data varchar(1000)
DECLARE @ID INT
SET @ID = 101
SET @data = 'Sears Tower'

INSERT INTO #ExistExample
VALUES (101,'<Buildings>
  <Building>
    <Name>Sears Tower</Name>
    <Floor1>Yes</Floor1>
    <Floor2>Yes</Floor2>
    <Floor3>No</Floor3>
  </Building>
  <Building>
    <Name>IDS Building</Name>
      <Floor1>Yes</Floor1>
      <Floor2>Yes</Floor2>
      <Floor3>Yes</Floor3>
  </Building>
</Buildings>')

--SELECT * FROM #ExistExample

SELECT 
c.value('(Name/text())[1]','varchar(25)') AS BuildingName,
c.value('(Floor1/text())[1]','varchar(25)') AS Floor1,
c.value('(Floor2/text())[1]','varchar(25)') AS Floor2,
c.value('(Floor3/text())[1]','varchar(25)') AS Floor3
FROM #ExistExample
CROSS APPLY XMLDocument.nodes('/Buildings/Building') as t(c)
WHERE c.exist('//Building/Name[.=sql:variable("@data")]') = 1
AND XMLID = @ID

Ответы [ 2 ]

1 голос
/ 09 июля 2011

Используйте

DriverDetails/DriverDetail[ID eq 1]/*[not(self::ID)]

или, если вы считаете это проще:

DriverDetails/DriverDetail[ID eq 1]/(PRN | Name))

Здесь предполагается, что (для обоих выражений XPath) выражение оценивается, имея в качестве начального узла контекста родительский элемент DriverDetails.

0 голосов
/ 10 июля 2011

Получил ответ.Это должно выглядеть так:

SELECT c.value('(Name/text())[1]','varchar(25)') AS BuildingName, 
c.value('(Floor1/text())[1]','varchar(25)') AS Floor1, 
c.value('(Floor2/text())[1]','varchar(25)') AS Floor2, 
c.value('(Floor3/text())[1]','varchar(25)') AS Floor3
 FROM #ExistExample 
CROSS APPLY XMLDocument.nodes('/Buildings/Building') as t(c) 
WHERE c.value('(Name/text())[1]','varchar(25)') = @data 
AND XMLID = @ID

Я не уверен, что это лучший способ или есть какой-то другой способ добиться этого.

...