SQL Server 2005의 XQuery를 사용하여 특정 속성 값이 있거나 해당 속성이 누락된 모든 노드를 선택합니다.

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

  •  01-07-2019
  •  | 
  •  

문제

업데이트:훨씬 더 철저한 예를 제공합니다.

제공된 처음 두 가지 솔루션은 제가 말하려는 내용과 정확히 일치했습니다. ~ 아니다 할 것.위치를 알 수 없습니다. 전체 문서 트리를 볼 수 있어야 합니다.따라서 컨텍스트로 지정된 /Books/를 사용하는 다음 라인의 솔루션은 작동하지 않습니다.

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

더 나은 예가 포함된 원래 질문:

SQL Server 2005의 XQuery 구현을 사용하여 XML 문서의 모든 노드를 한 번만 선택하고 원래 구조를 유지해야 합니다. 단, 특정 속성이 누락되었거나 해당 속성에 특정 값(매개변수로 전달됨)이 있는 경우에만 가능합니다.또한 쿼리는 미리 정의된 깊이에서 선택하는 대신 전체 XML 문서(하위 축 또는 자체 축)에서 작동해야 합니다.

즉, 각 개별 노드는 해당 노드와 모든 상위 노드에 속성이 없거나 단일 특정 값을 가진 속성이 있는 경우에만 결과 문서에 나타납니다.

예를 들어:

이것이 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>
    '

카테고리에 대한 매개변수 1의 결과는 다음과 같습니다.

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

카테고리에 대한 매개변수 2의 결과는 다음과 같습니다.

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

XSLT가 이 작업에 완벽하게 적합하다는 것을 알고 있지만 선택 사항은 아닙니다.우리는 SQL Server 2005에서 이 작업을 완전히 수행해야 합니다.T-SQL에서 완전히 수행할 수 있는 한 XQuery를 사용하지 않는 구현도 괜찮습니다.

도움이 되었습니까?

해결책

귀하의 예에서 실제로 달성하려는 것이 무엇인지 명확하지 않습니다.조건을 충족하는 노드를 제외하고 모든 노드가 제거된 새 XML을 반환하시겠습니까?그렇다면 이것은 MSSQL 2005에 내장되어 있지 않은 XSLT 변환 작업인 것 같습니다(UDF로 추가 가능: http://www.topxml.com/rbnews/SQLXML/re-23872_Performing-XSLT-Transforms-on-XML-Data-Stored-in-SQL-Server-2005.aspx).

노드 목록만 반환해야 하는 경우 다음 표현식을 사용할 수 있습니다.

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

하지만 나는 그것이 당신에게 필요한 것이 아니라는 인상을 받았습니다.좀 더 명확한 예를 제시해 주시면 도움이 될 것입니다.

편집하다:이 예는 실제로 더 명확합니다.내가 찾을 수 있는 최선의 방법은 다음과 같습니다.

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

아이디어는 XML에서 필요하지 않은 모든 노드를 삭제하여 원래 구조와 필요한 노드를 유지하는 것입니다.두 가지 예제를 테스트한 결과 원하는 결과가 나왔습니다.

하지만 수정하다 몇 가지 제한 사항이 있습니다. select 문에서는 사용할 수 없는 것 같습니다. 데이터를 제자리에서 수정해야 합니다.선택을 통해 이러한 데이터를 반환해야 하는 경우 원본 데이터를 복사한 다음 해당 테이블을 업데이트할 임시 테이블을 사용할 수 있습니다.이 같은:

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

도움이 되길 바랍니다.

다른 팁

질문은 실제로 명확하지 않지만 이것이 당신이 찾고 있는 것입니까?

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top