Поделиться через


Фильтрация значений при помощи sql:limit-field и sql:limit-value (SQLXML 4.0)

Количество строк, возвращаемых запросом к базе данных, можно ограничить на основе какого-либо значения. Для указания столбца базы данных, содержащего ограничивающие значения, и задания конкретного ограничивающего значения, которое будет использовано для фильтрации возвращенных данных, используются аннотации sql:limit-field иsql:limit-value.

Аннотация sql:limit-field указывает столбец, содержащий ограничивающее значение; эту аннотацию можно использовать для любого сопоставленного элемента или атрибута.

Аннотация sql:limit-value используется для задания ограничивающего значения в столбце, заданном аннотацией sql:limit-field. Аннотация sql:limit-value является необязательной. Если аннотация sql:limit-value не указана, предполагается, что она имеет значение NULL.

ПримечаниеПримечание

При работе с заметкой sql:limit-field, где сопоставляемый столбец SQL имеет тип real, SQLXML 4.0 выполняет преобразование значения sql:limit-value, указанного в схемах XML, как значение типа nvarchar. Для этого необходимо, чтобы десятичные граничные значения были указаны в полном экспоненциальном представлении. Дополнительные сведения см. в приведенном ниже Примере Б.

Примеры

Чтобы создать рабочие образцы на основе этих примеров, должны быть установлены следующие компоненты:

  • Собственный клиент Microsoft SQL Server

  • MDAC 2.6 или более поздние версии

В этих примерах для задания запросов XPath к схеме сопоставления XSD используются шаблоны.

А. Ограничение адресов заказчиков определенным типом адреса

В этом примере база данных содержит две таблицы:

  • Customer (CustomerID, CompanyName)

  • Addresses (CustomerID, AddressType, StreetAddress)

Заказчик может иметь адрес для доставки и/или адрес для выставления счетов. Столбец AddressType содержит значения Shipping и Billing.

Это схема сопоставления, в которой атрибут схемы ShipTo сопоставлен столбцу StreetAddress в отношении Addresses. Чтобы для этого атрибута возвращались только значения адресов для доставки, нужно задать аннотации sql:limit-field и sql:limit-value. Подобным же образом атрибут схемы BillTo возвращает только адреса для выставления счетов.

Схема:

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

Проверка образца запроса XPath к схеме

  1. В базе данных tempdb создайте две таблицы:

    USE tempdbCREATE TABLE Customer (CustomerID int primary key,                        CompanyName varchar(30))CREATE TABLE Addresses(CustomerID int,                        StreetAddress varchar(50),                       AddressType varchar(10))
    
  2. Добавьте образцы данных:

    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 Constitucion 2222 Mexico D.F.', 'shipping')INSERT INTO Addresses values           (2, '120 Hanover Sq., London', 'billing')INSERT INTO Addresses values           (2, 'Forsterstr. 57, Mannheim', 'shipping')
    
  3. Скопируйте приведенный выше код схемы и вставьте его в текстовый файл. Сохраните файл под именем LimitFieldValue.xml.

  4. Создайте следующий шаблон (LimitFieldValueT.xml) и сохраните его там же, где на предыдущем шаге была сохранена схема (LimitFieldValue.xml):

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

    Путь к каталогу для схемы сопоставления (LimitFieldValue.xml) задается относительно каталога, в котором сохранен шаблон. Можно также задать абсолютный путь, например:

    mapping-schema="C:\MyDir\LimitFieldValue.xml"
    
  5. Создайте и запустите тестовый сценарий SQLXML 4.0 (Sqlxml4test.vbs), чтобы выполнить шаблон.

    Дополнительные сведения см. в разделе Использование объектов ADO для выполнения запросов SQLXML.

Результирующий набор:

<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 Constitucion 2222 Mexico D.F.</ShipTo>   </Customer>   <Customer CustomerID="2" CompanyName="Company B">      <BillTo>120 Hanover Sq., London</BillTo>      <ShipTo>Forsterstr. 57, Mannheim</ShipTo>    </Customer> </ROOT>

Б. Ограничение результатов на основе значения скидки, имеющего тип данных real

В этом примере база данных содержит две таблицы:

  • Orders (OrderID)

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

Это схема сопоставления, в которой атрибут схемы сведений о заказе OrderID сопоставлен столбцу OrderID в отношении заказа. Для этого атрибута возвращаются только значения, равные 2.0000000e-001 (0.2), как указано для атрибута Discount с помощью аннотаций sql:limit-field и sql:limit-value.

Схема:

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

Проверка образца запроса XPath к схеме

  1. В базе данных tempdb создайте две таблицы:

    USE tempdbCREATE 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. Добавьте образцы данных:

    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. Сохраните схему (LimitFieldValue.xml) в каталоге.

  4. Создайте следующий сценарий проверки (TestQuery.vbs), замените МойСервер на имя компьютера с SQL Server и сохраните его в том же каталоге, в котором на предыдущем шаге была сохранена схема.

    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 = connstm.openresult ="none"strXPathQuery="/root"DBGUID_XPATH = "{EC2A4293-E898-11D2-B1B7-00C04F680C56}"cmd.Dialect = DBGUID_XPATHcmd.CommandText = strXPathQuerycmd.Properties("Mapping schema") = "LimitFieldReal.xml"cmd.Properties("Output Stream").Value = stmcmd.Properties("Output Encoding") = "utf-8"WScript.Echo "executing for xml query"On Error Resume Nextcmd.Execute , ,1024if err thenWscript.Echo err.descriptionWscript.Echo err.NumberWscript.Echo err.sourceOn Error GoTo 0elsestm.Position = 0result  = stm.ReadTextend ifWScript.Echo resultWscript.Echo "done"
    
  5. Запустите файл TestQuery.vbs, щелкнув его в проводнике Windows.

    Результирующий набор:

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