Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQLServer中选择xsi:type属性的值?_Sql_Xml_Sql Server 2005_Sql Server 2008_Xsd - Fatal编程技术网

如何在SQLServer中选择xsi:type属性的值?

如何在SQLServer中选择xsi:type属性的值?,sql,xml,sql-server-2005,sql-server-2008,xsd,Sql,Xml,Sql Server 2005,Sql Server 2008,Xsd,考虑到此xml文档: DECLARE @X XML (DOCUMENT search.SearchParameters) = '<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <parameter xsi:type="category" categoryID="38" />

考虑到此xml文档:

DECLARE @X XML (DOCUMENT search.SearchParameters)  = '<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <parameter xsi:type="category" categoryID="38" />
</parameters>';

但它不起作用。

如果不指定集合,这对我来说很好:

DECLARE @X XML
SET @x = N' 
<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <parameter  xsi:type="category" categoryID="38" />
</parameters>'
;

WITH    XMLNAMESPACES
        (
        'http://www.educations.com/Search/Parameters.xsd' as p,
        'http://www.w3.org/2001/XMLSchema-instance' as xsi
        )
SELECT  @X.value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')
(但您将无法在列上使用任何索引的
XML
),或对特定类型执行布尔检查:

WITH XMLNAMESPACES
        (
        'http://www.educations.com/Search/Parameters.xsd' as p
        )
SELECT @X.query('(/p:parameters/p:parameter)[1] instance of element(*, p:category?)')

我知道这是一个老问题,但是我昨天刚刚遇到这个问题,在SQL中没有找到明显的答案。但是,如果您控制了模式,我已经确定了一个解决方案

只需在每个具有相同名称的子类型上创建一个属性(下面的示例中为widgetType)

将每个属性设置为一个简单的xsi:string类型,并对其进行限制,以便唯一的值是子类型的名称。此外,将其设置为属性的默认值

如果将此模式绑定到xml数据列,则始终能够查询这个本质上反映xsi:type值的属性

我承认这并不理想,但它比将值转换为非类型并失去索引的好处要好

以下是一个例子:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
           elementFormDefault="qualified"
           xmlns="http://tempuri.org/XMLSchema.xsd"
           xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="widget"
              type="baseWidget" />
  <xs:complexType name="baseWidget"
                  abstract="true"></xs:complexType>
  <xs:complexType name="widgetA">
    <xs:complexContent>
      <xs:extension base="baseWidget">
        <xs:attribute name="widgetType"
                      default="widgetA">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="widgetA" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="widgetB">
    <xs:complexContent>
      <xs:extension base="baseWidget">
        <xs:attribute name="widgetType"
                      default="widgetB">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="widgetB" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

如果将xml条目放入绑定到此架构的表中,而不使用widgetType属性,则默认情况下SQL会自动添加该条目。它将始终可供您查询

<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:type="widgetA"
        widgetType="widgetA"
        xmlns="http://tempuri.org/XMLSchema.xsd" />

不幸的是,数据库中的列设置了架构。下面是模式的内容(我删除了“parameter”类型的其他子类型)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
           elementFormDefault="qualified"
           xmlns="http://tempuri.org/XMLSchema.xsd"
           xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="widget"
              type="baseWidget" />
  <xs:complexType name="baseWidget"
                  abstract="true"></xs:complexType>
  <xs:complexType name="widgetA">
    <xs:complexContent>
      <xs:extension base="baseWidget">
        <xs:attribute name="widgetType"
                      default="widgetA">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="widgetA" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="widgetB">
    <xs:complexContent>
      <xs:extension base="baseWidget">
        <xs:attribute name="widgetType"
                      default="widgetB">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="widgetB" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:type="widgetA"
        widgetType="widgetA"
        xmlns="http://tempuri.org/XMLSchema.xsd" />