Compartilhar via


Filtrando valores usando sql:limit-field e sql:limit-value (SQLXML 4.0)

Você pode limitar as linhas retornadas de uma consulta de banco de dados com base em algum valor limitador. As anotações sql:limit-field e sql:limit-value são usadas para identificar a coluna de banco de dados que contém os valores limitadores e especificar um valor limitador específico a ser usado para filtrar os dados retornados.

A anotação sql:limit-field é usada para identificar uma coluna que contém um valor limitador; ela é permitida em cada elemento ou atributo mapeado.

A anotação sql:limit-value é usada para especificar o valor limitado na coluna especificada na anotação sql:limit-field. A anotação sql:limit-value é opcional. Se sql:limit-value não for especificado, um valor NULL será assumido.

ObservaçãoObservação

Ao trabalhar com um sql:limit-field onde a coluna SQL mapeada é do tipo real, o SQLXML 4.0 executa a conversão no sql:limit-value conforme especificado em esquemas XML como um valor especificado por nvarchar. Isso exige que os valores de limite decimal sejam especificados usando notação científica completa. Para obter mais informações, veja o Exemplo B a seguir.

Exemplos

Para testar os exemplos a seguir, é necessário ter estes programas instalados:

  • Microsoft SQL Server Native Client

  • MDAC 2.6 ou posterior

Nestes exemplos, são usados modelos para especificar consultas XPath com base no esquema XSD de mapeamento.

A. Limitar os endereços de cliente retornados para um tipo de endereço específico

Neste exemplo, um banco de dados contém duas tabelas:

  • Customer (CustomerID, CompanyName)

  • Addresses (CustomerID, AddressType, StreetAddress)

Um cliente pode ter um endereço para cobrança e/ou um endereço para entrega. Os valores da coluna AddressType são Shipping e Billing.

Este é o esquema de mapeamento no qual o atributo de esquema ShipTo é mapeado para a coluna StreetAddress na relação Addresses. Os valores retornados para esse atributo são limitados somente aos endereços para entrega especificando as anotações sql:limit-field e sql:limit-value. De maneira semelhante, o atributo de esquema BillTo retorna somente o endereço para cobrança de um cliente.

Este é o esquema:

<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="CustAddr"
        parent="Customer"
        parent-key="CustomerID"
        child="Addresses"
        child-key="CustomerID" />
  </xsd:appinfo>
</xsd:annotation>

  <xsd:element name="Customer" sql:relation="Customer" >
   <xsd:complexType>
        <xsd:sequence>
        <xsd:element name="BillTo" 
                       type="xsd:string" 
                       sql:relation="Addresses" 
                       sql:field="StreetAddress"
                       sql:limit-field="AddressType"
                       sql:limit-value="billing"
                       sql:relationship="CustAddr" >
        </xsd:element>
        <xsd:element name="ShipTo" 
                       type="xsd:string" 
                       sql:relation="Addresses" 
                       sql:field="StreetAddress"
                       sql:limit-field="AddressType"
                       sql:limit-value="shipping"
                       sql:relationship="CustAddr" >
        </xsd:element>
        </xsd:sequence>
        <xsd:attribute name="CustomerID"   type="xsd:int" /> 
        <xsd:attribute name="CompanyName"  type="xsd:string" />
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Para testar uma consulta XPath de exemplo com relação ao esquema

  1. Crie duas tabelas no banco de dados tempdb:

    USE tempdb
    CREATE TABLE Customer (CustomerID int primary key, 
                           CompanyName varchar(30))
    CREATE TABLE Addresses(CustomerID int, 
                           StreetAddress varchar(50),
                           AddressType varchar(10))
    
  2. Adicione os dados de exemplo:

    INSERT INTO Customer values (1, 'Company A')
    INSERT INTO Customer values (2, 'Company B')
    
    INSERT INTO Addresses values
               (1, 'Obere Str. 57 Berlin', 'billing')
    INSERT INTO Addresses values
               (1, 'Avda. de la Constitución 2222 México D.F.', 'shipping')
    INSERT INTO Addresses values
               (2, '120 Hanover Sq., London', 'billing')
    INSERT INTO Addresses values
               (2, 'Forsterstr. 57, Mannheim', 'shipping')
    
  3. Copie o código de esquema acima e cole-o em um arquivo de texto. Salve o arquivo como LimitFieldValue.xml.

  4. Crie o modelo a seguir (LimitFieldValueT.xml) e salve-o no mesmo local onde você salvou o esquema (LimitFieldValue.xml) na etapa anterior:

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

    O caminho de diretório especificado para o esquema de mapeamento (LimitFieldValue.xml) é relativo ao diretório em que o modelo está salvo. Também é possível especificar um caminho absoluto, por exemplo:

    mapping-schema="C:\MyDir\LimitFieldValue.xml"
    
  5. Crie e use o Script de Teste SQLXML 4.0 (Sqlxml4test.vbs) para executar o modelo.

    Para obter mais informações, consulte Usando o ADO para executar consultas SQLXML.

Este é o resultado:

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"> 
  <Customer CustomerID="1" CompanyName="Company A"> 
     <BillTo>Obere Str. 57 Berlin</BillTo> 
     <ShipTo>Avda. de la Constitución 2222 México D.F.</ShipTo> 
  </Customer> 
  <Customer CustomerID="2" CompanyName="Company B"> 
     <BillTo>120 Hanover Sq., London</BillTo> 
     <ShipTo>Forsterstr. 57, Mannheim</ShipTo> 
   </Customer> 
</ROOT>

B. Limitar os resultados com base em um valor de desconto de dados de tipos reais

Neste exemplo, um banco de dados contém duas tabelas:

  • Orders (OrderID)

  • OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Price, Discount)

Este é o esquema de mapeamento no qual o atributo OrderID dos detalhes do pedido é mapeado para a coluna OrderID na relação de pedidos. Os valores retornados para esse atributo são limitados somente àqueles que têm um valor de 2.0000000e-001 (0.2) conforme especificado para o atributo Discount usando as anotações sql:limit-field e sql:limit-value.

Este é o esquema:

<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="OrderOrderDetails"
        parent="Orders"
        parent-key="OrderID"
        child="OrderDetails"
        child-key="OrderID" />
   </xsd:appinfo>
  </xsd:annotation>
  <xsd:element name="root" sql:is-constant="1">
   <xsd:complexType>
     <xsd:sequence>
       <xsd:element name="Order" sql:relation="Orders" >
          <xsd:complexType>
             <xsd:sequence>
                <xsd:element name="orderDetail" 
                       sql:relation="OrderDetails" 
                       sql:limit-field="Discount"                       sql:limit-value="2.0000000e-001"
                       sql:relationship="OrderOrderDetails">
                   <xsd:complexType>
                     <xsd:attribute name="OrderID"   /> 
                     <xsd:attribute name="ProductID" /> 
                     <xsd:attribute name="Discount"  /> 
                     <xsd:attribute name="Quantity"  /> 
                     <xsd:attribute name="UnitPrice" /> 
                   </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
           <xsd:attribute name="OrderID"/> 
          </xsd:complexType>
       </xsd:element>
     </xsd:sequence>
   </xsd:complexType>
  </xsd:element>
</xsd:schema>

Para testar uma consulta XPath de exemplo com relação ao esquema

  1. Crie duas tabelas no banco de dados tempdb:

    USE tempdb
    CREATE TABLE Orders ([OrderID] int NOT NULL ) ON [PRIMARY]
    ALTER TABLE Orders WITH NOCHECK ADD 
    CONSTRAINT [PK_Orders] PRIMARY KEY  CLUSTERED (
       [OrderID]
     )  ON [PRIMARY] 
    CREATE TABLE [OrderDetails] (
       [OrderID] int NOT NULL ,
       [ProductID] int NOT NULL ,
       [UnitPrice] money NULL ,
       [Quantity] smallint NOT NULL ,
       [Discount] real NOT NULL 
    ) ON [PRIMARY]
    
  2. Adicione os dados de exemplo:

    INSERT INTO Orders ([OrderID]) values (10248)
    INSERT INTO Orders ([OrderID]) values (10250)
    INSERT INTO Orders ([OrderID]) values (10251)
    INSERT INTO Orders ([OrderID]) values (10257)
    INSERT INTO Orders ([OrderID]) values (10258)
    INSERT INTO [OrderDetails] ([OrderID],[ProductID],[UnitPrice],[Quantity],[Discount]) values (10248,11,14,12,0)
    INSERT INTO [OrderDetails] ([OrderID],[ProductID],[UnitPrice],[Quantity],[Discount]) values (10250,51,42.4,35,0.15)
    INSERT INTO [OrderDetails] ([OrderID],[ProductID],[UnitPrice],[Quantity],[Discount]) values (10251,22,16.8,6,0.05)
    INSERT INTO [OrderDetails] ([OrderID],[ProductID],[UnitPrice],[Quantity],[Discount]) values (10257,77,10.4,15,0)
    INSERT INTO [OrderDetails] ([OrderID],[ProductID],[UnitPrice],[Quantity],[Discount]) values (10258,2,15.2,50,0.2)
    
  3. Salve o esquema (LimitFieldValue.xml) em um diretório.

  4. Crie o script de teste (TestQuery.vbs) a seguir, modifique MyServer para o nome do computador SQL Server e salve-o no mesmo diretório que você usou na etapa anterior para salvar o esquema:

    Set conn = CreateObject("ADODB.Connection")
    conn.Open "Provider=SQLOLEDB;Data Source=MyServer;Database=tempdb;Integrated Security=SSPI"
    conn.Properties("SQLXML Version") = "sqlxml.4.0" 
    Set cmd = CreateObject("ADODB.Command")
    Set stm = CreateObject("ADODB.Stream")
    Set cmd.ActiveConnection = conn
    stm.open
    result ="none"
    strXPathQuery="/root"
    DBGUID_XPATH = "{EC2A4293-E898-11D2-B1B7-00C04F680C56}"
    cmd.Dialect = DBGUID_XPATH
    cmd.CommandText = strXPathQuery
    cmd.Properties("Mapping schema") = "LimitFieldReal.xml"
    cmd.Properties("Output Stream").Value = stm
    cmd.Properties("Output Encoding") = "utf-8"
    WScript.Echo "executing for xml query"
    On Error Resume Next
    cmd.Execute , ,1024
    if err then
    Wscript.Echo err.description
    Wscript.Echo err.Number
    Wscript.Echo err.source
    On Error GoTo 0
    else
    stm.Position = 0
    result  = stm.ReadText
    end if
    WScript.Echo result
    Wscript.Echo "done"
    
  5. Execute o arquivo TestQuery.vbs clicando nele no Windows Explorer.

    Este é o resultado:

    <root>
      <Order OrderID="10248"/>
      <Order OrderID="10250"/>
      <Order OrderID="10251"/>
      <Order OrderID="10257"/>
      <Order OrderID="10258">
        <orderDetail OrderID="10258" 
                     ProductID="2" 
                     Discount="0.2" 
                     Quantity="50"/>
      </Order>
    </root>