SQL Server XQuery возвращает ошибку

Я выполняю запрос к столбцу типа данных XML в SQL Server 2012. Примером данных является:

<ns:Resume xmlns:ns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume"> <ns:Name> <ns:Name.Prefix></ns:Name.Prefix> <ns:Name.First>Shai</ns:Name.First> <ns:Name.Middle></ns:Name.Middle> <ns:Name.Last>Bassli</ns:Name.Last> <ns:Name.Suffix></ns:Name.Suffix> </ns:Name> ... </ns:Resume> 

Я пытаюсь написать запрос, чтобы вернуть первые имена.

Этот запрос возвращает список первых имен, как ожидалось:

 WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns) SELECT [Resume].query('(//ns:Name.First)').value('.[1]', 'nvarchar(100)') FROM HumanResources.JobCandidate; 

Однако этот запрос возвращает ошибку:

 WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns) SELECT [Resume].value('(//ns:Name.First)[1]', 'nvarchar(100)') FROM HumanResources.JobCandidate; 

Ошибка:

Msg 9314, уровень 16, состояние 1, строка 2
XQuery [HumanResources.JobCandidate.Resume.value ()]: Невозможно неявно распылять или применять «fn: data ()» к сложным элементам контента, найти тип «xs: anyType» внутри выбранного типа »(element (ns { http: // schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume }: Name.First, xs: string) | element (ns { http://schemas.microsoft.com/sqlserver/2004/07/adventure- works / Resume }: Name.First, xs: anyType))? '.

Есть кое-какое базовое понимание, что я здесь отсутствует, но я не уверен, что это такое. Может кто-нибудь просветить меня? Почему второй запрос возвращает ошибку?

Выражение XPath может привести к возврату нескольких строк для каждой строки в таблице SQL Server. Вам нужно использовать CROSS APPLY и вызов .nodes() чтобы получить .nodes() информацию:

 WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns) SELECT JobCandidateID, ResNames.value('(ns:Name.First)[1]', 'nvarchar(100)') FROM HumanResources.JobCandidate CROSS APPLY [Resume].nodes('/ns:Resume/ns:Name') AS XTbl(ResNames) 

Это должно возвращать все значения JobCandidateID и все имена, определенные в столбце Resume XML для каждой строки таблицы.

Если вы можете быть уверены, что в вашем столбце XML будет только один <name> , вы также можете сократить его до:

 WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume' AS ns) SELECT JobCandidateID, [Resume].value('(/ns:Resume/ns:Name/ns:Name.First)[1]', 'nvarchar(100)') FROM HumanResources.JobCandidate