Udostępnij przez


Określanie głębokość w relacji cyklicznych, przy użyciu sql:max-głębokość

W relacyjnych bazach danych tabela jest zaangażowany w relacji z samym sobą, jest nazywany relacji cyklicznej.Na przykład w relacji supervisee opiekuna, przechowywanie rekordów pracowników, w tabela jest zaangażowany w relacji z samym sobą.W takim wypadku w tabeli Pracownicy odgrywa rolę opiekuna stronie jeden relacji, a ta sama tabela odgrywa rolę supervisee po drugiej stronie.

Mapowania schematów mogą być relacji cyklicznych, gdzie elementu i jego element nadrzędny są tego samego typu.

Dlatego wartość predykatu prawdziwość to wyrażenie ma wartość true tylko dla węzłów, którego położenie kontekstu jest 3.

Należy wziąć pod uwagę w następującej tabela:

Emp (EmployeeID, FirstName, LastName, ReportsTo)

W tej tabela kolumna Szef przechowuje identyfikator pracownika kierownika.

Załóżmy, że chcesz wygenerować hierarchii XML pracowników, w którym Menedżer pracownika znajduje się na najwyższym poziomie w hierarchii, a pracownicy tego raportu do tego menedżera wyświetlania w odpowiedniej hierarchii jak to pokazano w następującym fragmencie XML próbki.Co zawiera ten fragment, jest drzewo cyklicznych dla pracownika 1.

<?xml version="1.0" encoding="utf-8" ?> 
<root>
  <Emp FirstName="Nancy" EmployeeID="1" LastName="Devolio">
     <Emp FirstName="Andrew" EmployeeID="2" LastName="Fuller" /> 
     <Emp FirstName="Janet" EmployeeID="3" LastName="Leverling">
        <Emp FirstName="Margaret" EmployeeID="4" LastName="Peacock">
          <Emp FirstName="Steven" EmployeeID="5" LastName="Devolio">
...
...
</root>

W tym fragmentu pracownika 5 raportów dla pracownika 4, pracownika 4 Raporty Pracownik 3 i raportach 3 i 2 pracowników do pracownika 1.

Do uzyskania tego wyniku, można użyć następujących schematu XSD i określić kwerendę XPath przed nim.Zawiera opis schematu <Pracownika> element typu EmployeeType składający się z <Pracownika> element podrzędność tego samego typu, EmployeeType. Jest to relacja cykliczna (elementu i jego element nadrzędny są tego samego typu).In addition, the schema uses a <sql:relationship> to describe the parent-child relationship between the supervisor and supervisee.Należy zauważyć, że w tym **<SQL:Relationship>**Pracownika jest w tabela podrzędnej i nadrzędnej.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:dt="urn:schemas-microsoft-com:datatypes"
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xsd:annotation>
    <xsd:appinfo>
      <sql:relationship name="SupervisorSupervisee"
                                  parent="Emp"
                                  parent-key="EmployeeID"
                                  child="Emp"
                                  child-key="ReportsTo" />
    </xsd:appinfo>
  </xsd:annotation>
  <xsd:element name="Emp" type="EmployeeType" 
                          sql:relation="Emp" 
                          sql:key-fields="EmployeeID" 
                          sql:limit-field="ReportsTo" />
  <xsd:complexType name="EmployeeType">
    <xsd:sequence>
      <xsd:element name="Emp" type="EmployeeType" 
                              sql:relation="Emp" 
                              sql:key-fields="EmployeeID"
                              sql:relationship="SupervisorSupervisee"
                              sql:max-depth="6" />
    </xsd:sequence> 
    <xsd:attribute name="EmployeeID" type="xsd:ID" />
    <xsd:attribute name="FirstName" type="xsd:string"/>
    <xsd:attribute name="LastName" type="xsd:string"/>
  </xsd:complexType>
</xsd:schema>

Ponieważ relacji cyklicznych, konieczne jest jakiś sposób, aby określić głębokość rekursji w schemacie.W przeciwnym wypadku wyniki będą nieograniczone rekursję (pracownik zgłoszenie do pracownika zgłoszenie pracownika i tak dalej).The sql:max-depth annotation allows you to specify how deep in the recursion to go.W tym przykładzie określonego, aby określić wartość w polu sql:max-depth, muszą wiedzieć, jak głęboko hierarchii zarządzania przechodzi w firmie.

Uwaga

Określa schemat sql:limit-field Adnotacja, ale nie określają sql:limit-value adnotacja. Ogranicza to węzeł najwyższego poziomu w hierarchii wynikowe do tylko tych pracowników, którzy nie jest zgłaszane dla każdej osoby.(Szef jest NULL). Określanie sql:limit-field a nie podając sql:limit-value (które domyślnie na wartość NULL) adnotacji wykonująca to. Wynikowy plik XML uwzględnienie wszystkich możliwych zgłoszenie drzewa (raportowania drzewo dla każdego pracownika w tabela) usunąć sql:limit-field Adnotacja ze schematu.

Uwaga

Poniższa procedura wykorzystuje bazy danych tempdb.

Aby przetestować kwerendę XPath próbki względem schematu

  1. Utwórz przykładową tabela o nazwie pracownika w bazie danych tempdb, na które wskazuje wirtualnego katalogu głównego.

    USE tempdb
    CREATE TABLE Emp (
           EmployeeID int primary key, 
           FirstName  varchar(20), 
           LastName   varchar(20), 
           ReportsTo int)
    
  2. Dodaj dane przykładowe to:

    INSERT INTO Emp values (1, 'Nancy', 'Devolio',NULL)
    INSERT INTO Emp values (2, 'Andrew', 'Fuller',1)
    INSERT INTO Emp values (3, 'Janet', 'Leverling',1)
    INSERT INTO Emp values (4, 'Margaret', 'Peacock',3)
    INSERT INTO Emp values (5, 'Steven', 'Devolio',4)
    INSERT INTO Emp values (6, 'Nancy', 'Buchanan',5)
    INSERT INTO Emp values (7, 'Michael', 'Suyama',6)
    
  3. Skopiować powyższy kod schematu i wkleić go do pliku tekstowego.Zapisz plik jako maxDepth.xml.

  4. Skopiuj następujący szablon i wkleić go do pliku tekstowego.Zapisz plik jako maxDepthT.xml w tym samym katalogu, w którym zapisano maxDepth.xml.W szablonie zwraca wszystkich pracowników w tabela pracownika.

    <ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
      <sql:xpath-query mapping-schema="maxDepth.xml">
        /Emp
      </sql:xpath-query>
    </ROOT>
    

    To ścieżka do katalogu określonego dla mapowania schematu (maxDepth.xml) jest względna w stosunku do katalogu, w którym są zapisywane w szablonie.Ścieżka bezwzględna również można określić, na przykład:

    mapping-schema="C:\MyDir\maxDepth.xml"
    
  5. Tworzenie i używanie skryptu testu 4.0 SQLXML (Sqlxml4test.vbs) do wykonać tego szablonu.Aby uzyskać więcej informacji zobaczPrzy użyciu obiektu ADO do wykonywania SQLXML bada 4.0.

Oto wynik:

<?xml version="1.0" encoding="utf-8" ?> 
<root>
  <Emp FirstName="Nancy" EmployeeID="1" LastName="Devolio">
  <Emp FirstName="Andrew" EmployeeID="2" LastName="Fuller" /> 
    <Emp FirstName="Janet" EmployeeID="3" LastName="Leverling">
      <Emp FirstName="Margaret" EmployeeID="4" LastName="Peacock">
        <Emp FirstName="Steven" EmployeeID="5" LastName="Devolio">
          <Emp FirstName="Nancy" EmployeeID="6" LastName="Buchanan">
            <Emp FirstName="Michael" EmployeeID="7" LastName="Suyama" /> 
          </Emp>
        </Emp>
      </Emp>
    </Emp>
  </Emp>
</root>

Uwaga

Do uzyskania różnych głębokość hierarchii w wyniku, zmień wartość sql:max-depth adnotacji w schemacie i wykonaj ponownie po każdej zmiany w szablonie.

W poprzednim schemacie wszystkich <Pracownika> elementy zostały dokładnie ten sam zestaw atrybutów)Pole IDPracownika, Imię, and Nazwisko).Następujące schematu został nieco zmodyfikowany do zwracania dodatkowych Szef atrybut wszystkich <Pracownika> elementy raportu do menedżera.

Na przykład ten fragment XML zawiera podwładnych pracownika 1:

<?xml version="1.0" encoding="utf-8" ?> 
<root>
<Emp FirstName="Nancy" EmployeeID="1" LastName="Devolio">
  <Emp FirstName="Andrew" EmployeeID="2" 
       ReportsTo="1" LastName="Fuller" /> 
  <Emp FirstName="Janet" EmployeeID="3" 
       ReportsTo="1" LastName="Leverling">
...
...

Jest to poprawione schematu:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:dt="urn:schemas-microsoft-com:datatypes"
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xsd:annotation>
    <xsd:documentation>
      Customer-Order-Order Details Schema
      Copyright 2000 Microsoft. All rights reserved.
    </xsd:documentation>
    <xsd:appinfo>
      <sql:relationship name="SupervisorSupervisee" 
                  parent="Emp"
                  parent-key="EmployeeID"
                  child="Emp"
                  child-key="ReportsTo" />
    </xsd:appinfo>
  </xsd:annotation>
  <xsd:element name="Emp" 
                   type="EmpType" 
                   sql:relation="Emp" 
                   sql:key-fields="EmployeeID" 
                   sql:limit-field="ReportsTo" />
  <xsd:complexType name="EmpType">
    <xsd:sequence>
       <xsd:element name="Emp" 
                    type="EmpType" 
                    sql:relation="Emp" 
                    sql:key-fields="EmployeeID"
                    sql:relationship="SupervisorSupervisee"
                    sql:max-depth="6"/>
    </xsd:sequence> 
    <xsd:attribute name="EmployeeID" type="xsd:int" />
    <xsd:attribute name="FirstName" type="xsd:string"/>
    <xsd:attribute name="LastName" type="xsd:string"/>
    <xsd:attribute name="ReportsTo" type="xsd:int" />
  </xsd:complexType>
</xsd:schema>

SQL:max-głębokość adnotacji

W schemacie, składający się z relacji cyklicznych należy jawnie określić głębokość rekursji w schemacie.Jest to wymagane, aby pomyślnie utworzyć odpowiednie dla XML JAWNE kwerendę, która zwraca żądane wyniki.

Użycie sql:max-depth adnotacji w schemacie, aby określić głębokość rekursji w relacji cyklicznych, opisanej w schemacie. Wartość sql:max-depth Adnotacja jest dodatnią liczbą całkowitą (od 1 do 50), wskazuje liczbę recursions: Wartość 1 zatrzymuje rekursji w elemencie, dla których sql:max-depth Adnotacja jest określony, wartość 2 zatrzymuje rekursję na następny poziom od elementu, w którym sql:max-depth określono; i tak dalej.

Uwaga

W podstawowej implementacji kwerendę XPath określonym schematem mapowania jest konwertowany na SELECT...DO JAWNEGO XML kwerendy.Ta kwerenda wymaga określić skończony głębokość rekursji.Im wyższa wartość określona dla sql:max-depth, tym większa FOR XML JAWNE kwerendę, która jest generowany. Może to zmniejszyć czas pobierania.

Uwaga

Updategrams i XML zbiorcze ładowanie zignorować adnotacji głębokość maks.Oznacza to, cyklicznych aktualizacji lub wstawienia stanie się niezależnie od tego, jakie wartości należy określić głębokość maks.

Określanie sql:max-głębokość na złożone elementy

The sql:max-depth annotation can be specified on any complex content element.

Elementy cykliczne

Jeśli sql:max-depth określono zarówno elementu nadrzędnego, jak i element podrzędność w relacji cyklicznych, sql:max-depth adnotacji na element nadrzędny ma wyższy priorytet. Na przykład w następującym schematem sql:max-depth Adnotacja jest określona zarówno obiektu nadrzędnego, jak i elementy podrzędność pracownika. W takim przypadek sql:max-depth=4, określonych na <Pracownika> element nadrzędny (odtwarzanie roli opiekuna), ma pierwszeństwo. The sql:max-depth specified on the podrzędność <Emp> element (playing a role of supervisee) is ignored.

Przykład B

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:dt="urn:schemas-microsoft-com:datatypes"
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xsd:annotation>
    <xsd:appinfo>
      <sql:relationship name="SupervisorSupervisee"
                                  parent="Emp"
                                  parent-key="EmployeeID"
                                  child="Emp"
                                  child-key="ReportsTo" />
    </xsd:appinfo>
  </xsd:annotation>
  <xsd:element name="Emp" type="EmployeeType" 
                          sql:relation="Emp" 
                          sql:key-fields="EmployeeID" 
                          sql:limit-field="ReportsTo" 
                          sql:max-depth="3" />
  <xsd:complexType name="EmployeeType">
    <xsd:sequence>
      <xsd:element name="Emp" type="EmployeeType" 
                              sql:relation="Emp" 
                              sql:key-fields="EmployeeID"
                              sql:relationship="SupervisorSupervisee"
                              sql:max-depth="2" />
    </xsd:sequence> 
    <xsd:attribute name="EmployeeID" type="xsd:ID" />
    <xsd:attribute name="FirstName" type="xsd:string"/>
    <xsd:attribute name="LastName" type="xsd:string"/>
  </xsd:complexType>
</xsd:schema>

Aby przetestować ten schemat, wykonaj kroki podane a przykład, we wcześniejszej części tego tematu.

Elementy Nonrecursive

Jeśli sql:max-depth Adnotacja jest określona na elemencie w schemacie, który nie powoduje żadnych rekursji, zostanie zignorowany. W schemacie następujące <Pracownika> element składa się z <Stała> element podrzędność, który z kolei zawiera <Pracownika> element podrzędność.

W tym schemacie sql:max-depth Adnotacja na <Stała> element jest ignorowany, ponieważ nie ma żadnych rekursji między <Pracownika> nadrzędny oraz <Stała> element podrzędność. Występuje rekursja między <Pracownika> element nadrzędny oraz <Pracownika> podrzędność. Określa schemat sql:max-depth adnotacji w obu. Dlatego też sql:max-depth Adnotacja określonymi na (element nadrzędny**<Pracownika>** w roli opiekuna) ma pierwszeństwo.

Ten predykat wartość wartość typu logiczny.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xsd:annotation>
    <xsd:appinfo>
      <sql:relationship name="SupervisorSupervisee" 
                  parent="Emp" 
                  child="Emp" 
                  parent-key="EmployeeID" 
                  child-key="ReportsTo"/>
    </xsd:appinfo>
  </xsd:annotation>
  <xsd:element name="Emp" 
               sql:relation="Emp" 
               type="EmpType"
               sql:limit-field="ReportsTo"
               sql:max-depth="1" />
    <xsd:complexType name="EmpType" >
      <xsd:sequence>
       <xsd:element name="Constant" 
                    sql:is-constant="1" 
                    sql:max-depth="20" >
         <xsd:complexType >
           <xsd:sequence>
            <xsd:element name="Emp" 
                         sql:relation="Emp" type="EmpType"
                         sql:relationship="SupervisorSupervisee" 
                         sql:max-depth="3" />
         </xsd:sequence>
         </xsd:complexType>
         </xsd:element>
      </xsd:sequence>
      <xsd:attribute name="EmployeeID" type="xsd:int" />
    </xsd:complexType>
</xsd:schema>

Aby przetestować ten schemat, wykonaj kroki przewidziane przykład A, we wcześniejszej części tego tematu.

Typy złożone pochodnego przez ograniczenie

Jeśli masz wyprowadzenie typu złożonego przez <ograniczenia>, nie można określić elementy odpowiadające im podstawowego typu złożonego sql:max-depth adnotacja. W takich przypadkach sql:max-depth adnotację można dodać do elementu typu pochodnego.

Z drugiej strony, jeśli masz wyprowadzenie typu złożonego przez <rozszerzenie>, można określić elementy odpowiadające im podstawowego typu złożonego sql:max-depth adnotacja.

Na przykład, następujące schematu XSD generuje błąd, ponieważ sql:max-depth Adnotacja jest określona na typ podstawowy. Ta adnotacja nie jest obsługiwana na typ, który wywodzi się przez <ograniczenia> z innego typu. Aby rozwiązać ten problem, należy zmienić schemat i określić sql:max-depth adnotacji w elemencie w typie pochodnym.

Przykład D

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:dt="urn:schemas-microsoft-com:datatypes"
            xmlns:msdata="urn:schemas-microsoft-com:mapping-schema">
  <xsd:complexType name="CustomerBaseType"> 
    <xsd:sequence>
       <xsd:element name="CID" msdata:field="CustomerID" />
       <xsd:element name="CompanyName"/>
       <xsd:element name="Customers" msdata:max-depth="3">
         <xsd:annotation>
           <xsd:appinfo>
             <msdata:relationship
                     parent="Customers"
                     parent-key="CustomerID"
                     child-key="CustomerID"
                     child="Customers" />
           </xsd:appinfo>
         </xsd:annotation>
       </xsd:element>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:element name="Customers" type="CustomerType"/>
  <xsd:complexType name="CustomerType">
    <xsd:complexContent>
       <xsd:restriction base="CustomerBaseType">
          <xsd:sequence>
            <xsd:element name="CID" 
                         type="xsd:string"/>
            <xsd:element name="CompanyName" 
                         type="xsd:string"
                         msdata:field="CName" />
            <xsd:element name="Customers" 
                         type="CustomerType" />
          </xsd:sequence>
       </xsd:restriction>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema> 

W schemacie, sql:max-depth jest określony w CustomerBaseType Typ złożony. Określa również schematu <Odbiorcy> element typu CustomerType, który pochodzi od CustomerBaseType. Kwerendy XPath określona dla takich schematu wygeneruje błąd, ponieważ sql:max-depth nie jest obsługiwana na element, który jest zdefiniowany w ograniczeń typu podstawowego.

Schematy z hierarchią szczegółowa

Użytkownik może mieć schematu, zawierającą głębokie hierarchii, w którym element zawiera element podrzędność, który z kolei zawiera inny element podrzędność, i tak dalej.Jeśli sql:max-depth adnotacji określona w schemacie takie generuje dokumentu XML, który zawiera hierarchię poziomów więcej niż 500 (z element najwyższego poziom poziom 1, jego podrzędność poziom 2 i tak dalej), zwracany jest błąd.