Aracılığıyla paylaş


Sql:max-depth Kullanarak Özyinelemeli İlişkilerde Derinlik Belirtme

Şunlar için geçerlidir:SQL ServerAzure SQL Veritabanı

İlişkisel veritabanlarında, bir tablo kendisiyle ilişki içinde olduğunda, buna özyinelemeli ilişki denir. Örneğin, bir süpervizör-denetli ilişkisinde, çalışan kayıtlarını saklayan bir tablo kendisiyle ilişki içinde olur. Bu durumda, çalışan masası ilişkinin bir tarafında süpervizör rolünde, aynı masa diğer tarafta ise denetleyici rolünü oynar.

Eşleme şemaları, bir eleman ve atasının aynı türde olduğu özyinelemeli ilişkileri içerebilir.

Örnek A

Aşağıdaki tabloyu ele alalım:

Emp (EmployeeID, FirstName, LastName, ReportsTo)  

Bu tabloda, ReportsTo sütununda yöneticinin çalışan kimliği yer alır.

Yönetici çalışanın hiyerarşinin en üstünde olduğu ve o yöneticiye rapor veren çalışanların aşağıdaki örnek XML parçasında gösterildiği gibi ilgili hiyerarşide göründüğü bir XML çalışan hiyerarşisi oluşturmak istediğinizi varsayalım. Bu parçanın gösterdiği şey, çalışan 1 için özyinelemeli ağac .

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

Bu parçada, çalışan 5 çalışan 4'e, çalışan 4 çalışan 3'e, 3 ve 2 çalışan 1'e rapor veriyor.

Bu sonucu elde etmek için aşağıdaki XSD şemasını kullanabilir ve ona karşı bir XPath sorgusu belirleyebilirsiniz. Şema, aynı türden bir EmployeeType olan bir EmployeeType adlı bir Employ> elemanını tanımlar.<<> Bu özyinelemeli bir ilişkidir (element ve atası aynı türdendir). Ayrıca, şema süpervizör ile denetleyici arasındaki ebeveyn-çocuk ilişkisini tanımlamak için< sql:ilişkisi> kullanır. Bu <sql:ilişkisinde> Emp hem ebeveyn hem de çocuk tablodur.

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

İlişki özyinelemeli olduğu için, şemadaki özyineleme derinliğini belirtmenin bir yolu gerekir. Aksi takdirde, sonuç sonsuz bir özyineleme olur (çalışan çalışana rapor verir, çalışana rapor verir ve benzeri). sql:max-derinlik açıklaması, özyinelemenin ne kadar derinliğe ineceğini belirtmenize olanak tanır. Bu özel örnekte, sql:max-depth için bir değer belirtmek için, şirkette yönetim hiyerarşisinin ne kadar derinleştiğini bilmeniz gerekir.

Uyarı

Şema sql:limit alan açıklamasını belirtir, ancak sql:limit-değer açıklamasını belirtmez. Bu, ortaya çıkan hiyerarşideki en üst düğümü yalnızca kimseye rapor vermeyen çalışanlarla sınırlar. (Raporlar NULL.) sql:limit-field belirtmek ve sql:limit-value (varsayılan olarak NULL) belirtmemesi bunu sağlar. Ortaya çıkan XML'in her olası raporlama ağacını (tablodaki her çalışan için raporlama ağacı) içermesini istiyorsanız, sql:limit alanı açıklamasını şemadan çıkarın.

Uyarı

Aşağıdaki prosedür tempdb veritabanını kullanır.

Örnek XPath sorgusunu şema karşısında test etmek için

  1. Sanal kök noktasının işaret ettiği tempdb veritabanında Emp adlı örnek bir tablo oluşturun.

    USE tempdb  
    CREATE TABLE Emp (  
           EmployeeID int primary key,   
           FirstName  varchar(20),   
           LastName   varchar(20),   
           ReportsTo int)  
    
  2. Bu örnek veriyi ekleyin:

    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. Yukarıdaki şema kodunu kopyalayıp metin dosyasına yapıştırın. Dosyayı maxDepth.xmlolarak kaydet.

  4. Aşağıdaki şablonu kopyalayın ve bir metin dosyasına yapıştırın. Dosyayı aynı dizinde maxDepthT.xml olarak kaydet maxDepth.xml. Şablondaki sorgu, Emp tablosundaki tüm çalışanları geri getirir.

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

    Eşleme şeması (maxDepth.xml) için belirtilen dizin yolu, şablonun kaydedildiği dizine görecelidir. Mutlak bir yol da belirtilebilir, örneğin:

    mapping-schema="C:\MyDir\maxDepth.xml"  
    
  5. Şablonu çalıştırmak için SQLXML 4.0 Test Script'i (Sqlxml4test.vbs) oluşturun ve kullanın. Daha fazla bilgi için bkz. SQLXML 4.0 Sorguları Yürütmek için ADO Kullanma.

Sonuç şu şekildedir:

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

Uyarı

Sonuçta farklı derinliklerde hiyerarşiler oluşturmak için, şemadaki sql:max-derinlik açıklamasının değerini değiştirin ve her değişiklikten sonra şablonu tekrar çalıştırın.

Önceki şemada, tüm <EmployeeID> , FirstName ve LastName (EmployeeID, FirstName ve LastName) tam olarak aynı öznitelik setine sahipti. Aşağıdaki şema, yöneticiye rapor veren tüm <Emp> öğeleri için ek bir ReportsTo attanatması döndürülerek biraz değiştirilmiştir.

Örneğin, bu XML parçası çalışan 1'in astlarını gösterir:

<?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">  
...  
...  

Revize edilmiş şema şöyledir:

<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-derinlik Açıklaması

Özyinelemeli ilişkilerden oluşan bir şemada, özyineleme derinliği şemada açıkça belirtilmelidir. Bu, istenen sonuçları geri getiren uygun XML EXPLICIT sorgusunu başarılı bir şekilde üretmek için gereklidir.

Şemadaki sql:max-derinlik açıklamasını kullanarak şemada tanımlanan özyinelemeli ilişkideki özyineleme derinliğini belirtir. sql:max-derinlik açıklamasının değeri, özyineleme sayısını gösteren pozitif tam sayıdır (1'den 50'yedir): 1 değeri, sql:max-derinlik açıklamasının belirtildiği elemandaki özyinelemeyi durdurur; 2 değeri, SQL:max-derinliğinin belirtildiği elemandan sonraki seviyede özyinelemeyi durdurur; ve benzeri.

Uyarı

Temel uygulamada, bir eşleme şemasına karşı belirtilen bir XPath sorgusu bir SELECT'e dönüştürülür ... XML için açık bir sorgu. Bu sorgu, sonlu bir özyineleme derinliği belirtmenizi gerektirir. sql:max-depth için belirttiğiniz değer ne kadar yüksekse, oluşturulan FOR XML EXPLICIT sorgusu o kadar büyüktür. Bu, geri alma süresini yavaşlatabilir.

Uyarı

Updategrams ve XML Bulk Load ise maksimum derinlik açıklamasını görmezden gelir. Bu, maksimum derinlik için belirttiğiniz değere bakılmaksızın özyinelemeli güncellemeler veya eklemeler gerçekleşeceği anlamına gelir.

Karmaşık Elemanlar için sql:max-derinliği belirtilmesi

sql:max-derinlik açıklaması herhangi bir karmaşık içerik öğesi üzerinde belirtilebilir.

Özyinelemeli Elementler

Eğer sql:max-depth hem ana eleman hem de alt eleman için özyinelemeli bir ilişkide belirtilirse, ebeveyn öğesinde belirtilen sql:max-derinlik açıklaması önceliklidir. Örneğin, aşağıdaki şemada, sql:max-derinlik açıklaması hem ana hem de alt çalışan elemanlarında belirtilmiştir. Bu durumda, Emp> ebeveyn elemanında belirtilen sql:max-depth=4< (süpervizör rolünde) öncelik alır. Child <Emp> öğesinde belirtilen sql:max-derinliği (denetleyici rolünü oynayarak) göz ardı edilir.

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

Bu şemayı test etmek için, bu konunun başındaki Örnek A için verilen adımları takip edin.

Özyinelemesiz Öğeler

Eğer sql:max-derinlik açıklaması, şemadaki bir elemanda belirtilirse ve bu bir eleman herhangi bir özyinelemeye neden olmazsa, bu göz ardı edilir. Aşağıdaki şemada, bir< Emp> elemanı <bir Sabit> çocuk elemandan oluşur ve bu eleman ise bir <Emp> çocuk elemanına sahiptir.

Bu şemada, Constant> elemanında belirtilen sql:max-derinlik açıklaması< göz ardı edilir çünkü Emp> ebeveyni ile Constant çocuk elemanı arasında< özyineleme yoktur.>< Ama Emp> atası ile Emp çocuğu arasında< bir yineneleme vardır.>< Şema, her iki konuda da sql:max-derinlik açıklamasını belirtir. Bu nedenle, atada belirtilen sql:max-derinlik açıklaması (<süpervizör rolünde Emp> ) önceliklidir.

Örnek C

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

Bu şemayı test etmek için, bu konunun önceki Örneği A için verilen adımları takip edin.

Kısıtlama ile Türetilen Karmaşık Tipler

Eğer kısıtlama> ile bir kompleks tür< türevasyonu varsa, ilgili temel kompleks tipin elemanları sql:max-derinlik açıklamasını belirtemez. Bu durumlarda, türetilmiş tipin elemanına sql:max-derinlik açıklaması eklenebilir.

Öte yandan, eğer uzantılı> olarak bir kompleks tür< türeviniz varsa, ilgili temel kompleks tipin elemanları sql:max-derinlik açıklamasını belirtebilir.

Örneğin, aşağıdaki XSD şeması bir hata oluşturur çünkü sql:max-derinlik açıklaması temel tipte belirtilmiştir. Bu açıklama, başka bir tipten kısıtlama> yoluyla türetilen< bir tipte desteklenmez. Bu sorunu çözmek için, şemayı değiştirmeli ve türetilmiş türdeki eleman üzerinde sql:max-derinlik notasyonunu belirtmelisiniz.

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

Şemada, sql:max-derinliği bir CustomerBaseType kompleks tipinde belirtilir. Şema ayrıca CustomerBaseType'tan türetilen CustomerType tipli bir <Müşteri> öğesini belirtir. Böyle bir şemada belirtilen bir XPath sorgusu hata oluşturur, çünkü sql:max-depth , kısıtlama taban türünde tanımlanmış bir elemanda desteklenmez.

Derin Hiyerarşili Şemalar

Bir şemanız olabilir; bir öğenin bir çocuk öğe içerdiği, o da başka bir ço öğeyi içeren derin bir hiyerarşi içerebilir. Böyle bir şemada belirtilen sql:max-derinlik açıklaması, 500'den fazla seviyeden oluşan bir hiyerarşi içeren bir XML belgesi oluşturursa (üst seviye eleman seviye 1, çocuğu seviye 2 vb.), hata döner.