Verwenden von SQL Server 2005 von XQuery wählen alle Knoten mit einem bestimmten Attributwert oder mit diesem Attribut fehlt

StackOverflow https://stackoverflow.com/questions/90023

  •  01-07-2019
  •  | 
  •  

Frage

Update:. Ein viel gründlichere Beispiel geben

Die ersten beiden angebotenen Lösungen waren direkt nach dem Vorbild das, was ich versuche, zu sagen, nicht zu tun. Ich kann wissen Lage nicht, muss es auf dem gesamten Dokument Baum schauen können. So eine Lösung in dieser Richtung, mit / Bücher / als Kontext angegeben wird nicht funktionieren:

SELECT x.query('.') FROM @xml.nodes('/Books/*[not(@ID) or @ID = 5]') x1(x)

Original Frage mit besserem Beispiel:

Verwenden von SQL Server 2005 der XQuery-Implementierung Ich brauche alle Knoten in einem XML-Dokument zu wählen, nur jeweils einmal und ihre ursprüngliche Struktur zu halten, aber nur, wenn sie ein bestimmtes Attribut fehlen, oder dass Attribut hat einen bestimmten Wert (gebenen durch Parameter). Die Abfrage hat auch eher auf dem gesamten XML-Dokument (descendant-or-self-Achse) zu arbeiten, als mit einer vorgegebenen Tiefe auswählen.

Das heißt, jeder einzelne Knoten im resultierenden Dokument erscheint nur, wenn es und jeder seiner Vorfahren das Attribut fehlt, oder das Attribut mit einem einzigen bestimmten Wert.

Beispiel:

Wenn das der XML:

    DECLARE @Xml XML
    SET @Xml =
    N'
<Library>
  <Novels>
    <Novel category="1">Novel1</Novel>
    <Novel category="2">Novel2</Novel>
    <Novel>Novel3</Novel>
    <Novel category="4">Novel4</Novel>
  </Novels>
  <Encyclopedias>
    <Encyclopedia>
      <Volume>A-F</Volume>
      <Volume category="2">G-L</Volume>
      <Volume category="3">M-S</Volume>
      <Volume category="4">T-Z</Volume>
    </Encyclopedia>
  </Encyclopedias>
  <Dictionaries category="1">
    <Dictionary>Webster</Dictionary>
    <Dictionary>Oxford</Dictionary>
  </Dictionaries>
</Library>
    '

Ein Parameter von 1 für die Kategorie würde dies zur Folge haben:

<Library>
  <Novels>
    <Novel category="1">Novel1</Novel>
    <Novel>Novel3</Novel>
  </Novels>
  <Encyclopedias>
    <Encyclopedia>
      <Volume>A-F</Volume>
    </Encyclopedia>
  </Encyclopedias>
  <Dictionaries category="1">
    <Dictionary>Webster</Dictionary>
    <Dictionary>Oxford</Dictionary>
  </Dictionaries>
</Library>

Ein Parameter von 2 für Kategorie in dieser Folge hätte:

<Library>
  <Novels>
    <Novel category="2">Novel2</Novel>
    <Novel>Novel3</Novel>
  </Novels>
  <Encyclopedias>
    <Encyclopedia>
      <Volume>A-F</Volume>
      <Volume category="2">G-L</Volume>
    </Encyclopedia>
  </Encyclopedias>
</Library>

Ich weiß, XSLT für diesen Job bestens geeignet ist, aber es ist keine Option. Wir müssen diese Server vollständig in SQL erreichen 2005. Alle Implementierungen nicht mit XQuery sind zu fein, solange es vollständig in T-SQL getan werden kann.

War es hilfreich?

Lösung

Es ist nicht klar, für mich aus Ihrem Beispiel, was Sie tatsächlich zu erreichen versuchen. Möchten Sie eine neue XML mit allen Knoten außer denen gezupft zurückzukehren, die die Bedingung erfüllen? Wenn ja, dann sieht es wie der Job für eine XSLT-Transformation, die ich nicht glaube, es ist eingebaut in MSSQL 2005 (kann als UDF hinzugefügt werden: http://www.topxml.com/rbnews/SQLXML/ Wieder 23872_Performing-XSLT-Transformationen-on-XML-Data-Stored-in-SQL-Server-2005.aspx ).

Wenn Sie nur die Liste der Knoten zurückgeben müssen, dann können Sie diesen Ausdruck verwenden:

//Book[not(@ID) or @ID = 5]

, aber ich habe den Eindruck, dass es nicht das, was Sie brauchen. Es würde helfen, wenn Sie ein deutlicheres Beispiel zur Verfügung stellen können.

Bearbeiten : Dieses Beispiel ist in der Tat mehr klar. Das Beste, was ich finden konnte, ist dies:

SET @Xml.modify('delete(//*[@category!=1])')
SELECT @Xml

Die Idee ist aus der XML alle Knoten zu löschen, die Sie nicht benötigen, so dass Sie mit der ursprünglichen Struktur und die benötigten Knoten bleiben. Getestet habe ich mit zwei Beispielen und es erzeugt das gewünschte Ergebnis.

Allerdings modify hat einige Einschränkungen - es scheint, dass Sie nicht in einer select-Anweisung verwenden können, hat es Daten an seinem Platz zu ändern. Wenn Sie diese Daten mit einem ausgewählten zurückzukehren brauchen Sie eine temporäre Tabelle verwenden, in dem die ursprünglichen Daten zu kopieren und dann die Tabelle aktualisieren. So etwas wie folgt aus:

INSERT INTO #temp VALUES(@Xml)
UPDATE #temp SET data.modify('delete(//*[@category!=2])')

Ich hoffe, das hilft.

Andere Tipps

Die Frage ist nicht wirklich klar, aber das ist, was Sie suchen?

DECLARE @Xml AS XML
        SET @Xml =
        N'
        <Books>
                <Book ID="1">Book1</Book>
                <Book ID="2">Book2</Book>
                <Book ID="3">Book3</Book>
                <Book>Book4</Book>
                <Book ID="5">Book5</Book>
                <Book ID="6">Book6</Book>
                <Book>Book7</Book>
                <Book ID="8">Book8</Book>
        </Books>
        '
DECLARE @BookID AS INT
SET @BookID = 5
DECLARE @Result AS XML

SET @result = (SELECT @xml.query('//Book[not(@ID) or @ID = sql:variable("@BookID")]'))
SELECT @result
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top