2

Introduction

I'm trying to query an xml column in SQL server 2008, but I get an error I can't fix.

This is the schema I use:

CREATE XML SCHEMA COLLECTION PublicationSchema AS '
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
   <xs:import namespace="http://www.w3.org/XML/1998/namespace"
              schemaLocation="xml.xsd"/>
   <xs:element name="publication">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="metadata"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:element name="meta">
      <xs:complexType>
         <xs:attributeGroup ref="attlist-meta"/>
      </xs:complexType>
   </xs:element>
   <xs:attributeGroup name="attlist-meta">
      <xs:attribute name="name" use="required"/>
      <xs:attribute name="content"/>
      <xs:attribute name="scheme"/>
   </xs:attributeGroup>
   <xs:element name="metadata">
      <xs:complexType>
         <xs:sequence>
            <xs:element maxOccurs="unbounded" ref="meta"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   </xs:schema>'
GO

I create table with an XML column using the schema: create table test (content XML(PublicationSchema))

I insert some data:

insert into test values(N'<?xml version="1.0" encoding="UTF-16"?>
<publication>
    <metadata>
        <meta name="type" content="plan" scheme="city"/>
        <meta name="statistics" content="second" scheme="informationtype"/>
    </metadata>
</publication>')

Problem

When i execute a query:

select * from test
where Content.exist('/publication/metadata/meta[@name] = "type"') = 1

I get this error:

 Msg 2213, Level 16, State 1, Line 3
 XQuery [test.content.exist()]: Cannot atomize/apply data()
    on expression that contains type 'meta' within inferred
    type 'element(meta,#anonymous) *'

Question

Doesn anyone know what I can do to fix this query?

user369117
  • 775
  • 1
  • 8
  • 19

1 Answers1

2

You have a syntax error in your exist function. You need to have the comparison between the brackets.

select * 
from test
where Content.exist('/publication/metadata/meta[@name = "type"]') = 1

This will work just fine with the XML you have if it was not for your schema. Applying that schema will give the error you referred to in a comment because you have no data type for the attribute name.
You have two options to fix this. Alter the schema to include data types or rewrite the query above tricking SQL Server to treat the attribute as not part of schema.

Specifying a data type for name would look like this.

<xs:attributeGroup name="attlist-meta">
   <xs:attribute name="name" use="required" type="xs:string"/>
   <xs:attribute name="content"/>
   <xs:attribute name="scheme"/>
</xs:attributeGroup>

If you can not modify the schema you can use this query instead.

select *
from test
where Content.query('/publication/metadata/meta').exist('/*[@name = "type"]') = 1
Mikael Eriksson
  • 136,425
  • 22
  • 210
  • 281