I am new to extracting data from XML column using SQL, I did try with other simple format but this one is a bit tricky.
XML column name is "Data" and below is the value.
<SpecificationDataDto
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/Dummy.Sample.API.TransferObjects.Dto">
<Narratives>
<AnswerDto>
<AddressData />
<AddressResponseType i:nil="true" />
<Answers
xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d4p1:string>Loose Print</d4p1:string>
</Answers>
<ComponentOrderNumber>3</ComponentOrderNumber>
<Index>0</Index>
<IsQuantity>false</IsQuantity>
<MasterQuestionId i:nil="true" />
<MasterQuestionTitle i:nil="true" />
<MasterQuestionTitleResourceKey i:nil="true" />
<ParentQuestionGroupId i:nil="true" />
<ParentQuestionGroupIndex i:nil="true" />
<ParentQuestionGroupTitle i:nil="true" />
<PermutationId>65922bf8-6468-40f2-967c-27547412ba2b</PermutationId>
<PermutationOrder>0</PermutationOrder>
<ProductSpecificationLabel />
<ProductSpecificationLabelResourceKey>65A4E3D8-9FF7-48D9-B3F8-0E2D4D23A1B8</ProductSpecificationLabelResourceKey>
<QuestionGroupId i:nil="true" />
<QuestionGroupIndex i:nil="true" />
<QuestionGroupOrderNumber i:nil="true" />
<QuestionGroupTitle i:nil="true" />
<QuestionId>e575d4ac-5dfb-4170-c5c0-08da85c9a9ed</QuestionId>
<QuestionOrderNumber>1</QuestionOrderNumber>
<QuestionTitle>Product category</QuestionTitle>
<QuestionTitleResourceKey>81B4FFBC-4503-4E48-83C0-17FBB227384B</QuestionTitleResourceKey>
<ResponseIds
xmlns:d4p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d4p1:guid>c4ed5170-6634-4aad-c054-08da7f653c36</d4p1:guid>
</ResponseIds>
<UpdateDate i:nil="true" />
</AnswerDto>
</Narratives>
</SpecificationDataDto>
I tried below but no luck
WITH XMLNAMESPACES ('http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS d4p1)
, CTE as (
SELECT Order
,t.c.value('(*/QuestionTitle)[1]', 'Varchar(250)') AS Question
,t.c.value('(*/d4p1:string)[1]', 'Varchar(250)') AS Answer
FROM SchemaName.DatabaseName.TableName
CROSS APPLY Data.nodes('*/SpecificationDataDto/Narratives/AnswerDto') t(c)
WHERE Order = '737B4994'
)
select * from CTE
I am expecting the below values to come out for this order in 2 columns,
QuestionTitle = Product category
d4p1:string = Loose Print
I have a table that lists some user details.
ID
GUID
Username
Password
Data
1
a2a8s7d4d
xswe
xxxxxx
XML
2
aer335mla
user
xxxxxx
XML
The Data column contains data using XML. Below is a sample from the table.
<UserInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ComponentFramework">
<ActiveDirectoryUser>false</ActiveDirectoryUser>
<CanUpdateMasterData>false</CanUpdateMasterData>
<CanUploadFiles>false</CanUploadFiles>
<ChangePassword>false</ChangePassword>
<CustomDataPageSize>false</CustomDataPageSize>
<CustomMasterDataPageSize>false</CustomMasterDataPageSize>
<DataPageSize>100</DataPageSize>
<Disabled>true</Disabled>
<Displayname>Pål</Displayname>
<Email i:nil="true" />
<EnforcePasswordPolicy>false</EnforcePasswordPolicy>
<EnvironmentIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<GUID i:nil="true" />
<GeoLocation>
<City i:nil="true" />
<Country i:nil="true" />
<CountryCode i:nil="true" />
<Ip i:nil="true" />
<Isp i:nil="true" />
<Lat>0</Lat>
<Lon>0</Lon>
<Org i:nil="true" />
<Query i:nil="true" />
<Region i:nil="true" />
<RegionName i:nil="true" />
<Status i:nil="true" />
<Timezone i:nil="true" />
<Zip i:nil="true" />
</GeoLocation>
<GroupIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<HttpLink i:nil="true" />
<JobIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<LastLoggedIn>2015-06-11T19:04:44.6407074+05:30</LastLoggedIn>
<MasterDataPageSize>1000</MasterDataPageSize>
<ModifyImages>false</ModifyImages>
<QualityControl>false</QualityControl>
<QualityControlGroupId i:nil="true" />
<Review>false</Review>
<ReviewGroupId i:nil="true" />
<SecurityToken i:nil="true" />
<ShowTrackerPage>false</ShowTrackerPage>
<StatIdList xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<Username><new user></Username>
<Usertype>Power</Usertype>
</UserInfo>
I'm trying to match users that have their accounts disabled. Using the below sql query.
select * from [ATC_Config].[dbo].[Users] where [ATC_Config].[dbo].[Users].[Data].value('/UserInfo/Disabled[1]','nvarchar(MAX)') = 'true'
But SSMS is giving me an error Cannot call methods on nvarchar(max) and highlight my column which Data. I tried few suggestions in SO and in MSDN but nothing helped. Can someone show me what am I doing wrong?
Because your sample XML contains a default namespace definition you'll need to declare that in your value XQuery or via with xmlnamespaces.
Here's how you can do that with value...
select *
from dbo.Users
where cast(Data as xml).value(N'
declare default element namespace "http://schemas.datacontract.org/2004/07/ComponentFramework";
(/UserInfo/Disabled)[1]',N'nvarchar(max)') = N'true';
Or by using with xmlnamespaces:
with xmlnamespaces(default N'http://schemas.datacontract.org/2004/07/ComponentFramework')
select *
from dbo.Users
where cast(Data as xml).value(N'(/UserInfo/Disabled)[1]', N'nvarchar(max)') = N'true';
You need to add the namespace, and you need to cast the value to xml. This is easier if you use with because it applies to the whole query.
A slightly more efficient version of #AlwaysLearning's answer is to use exist and /text()
with xmlnamespaces (
default N'http://schemas.datacontract.org/2004/07/ComponentFramework'
)
select *
from dbo.Users u
where cast(u.Data as xml).exist(N'/UserInfo/Disabled[text() = "true"]') = 1;
db<>fiddle
I strongly suggest you store the Data column as xml in the first place, as casting is inefficient.
My XML looks like
<?xml version="1.0" encoding="UTF-8"?>
<ListasExternasFull xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Encabezado xmlns="http://tempuri.org/">
<Acceso>true</Acceso>
<Usuario>FENALCO</Usuario>
<Contrasena>FENALCO2015PROD</Contrasena>
<Documento>24944511</Documento>
<TipoDocumento>1</TipoDocumento>
<Nombres />
<Apellidos />
<Login />
<Fecha>2016-01-23T17:07:56.1986626-05:00</Fecha>
<IdConsulta>0</IdConsulta>
</Encabezado>
<objContraloria xmlns="http://tempuri.org/">
<Id>92798</Id>
<IsContraloria>false</IsContraloria>
<Cedula>24944511</Cedula>
<Nombre />
<Departamento />
<Municipio />
<EntidadAfectada />
<FallosACargo />
<TipoResponsabilidad />
<TipoPersona />
<ReportadoPor />
<FechaControl>2016-01-23T17:03:43.13</FechaControl>
<Excepcion />
</objContraloria>
<objFosyga xmlns="http://tempuri.org/">
<Id>92496</Id>
<IsFosyga>false</IsFosyga>
<NumeroIdentidad>24944511</NumeroIdentidad>
<Nombre />
<Apellido />
<Departamento />
<Municipio />
<Estado />
<Entidad />
<Regimen />
<FechaAfiliacion />
<TipoAfiliado />
<FechaControl>2016-01-23T17:07:56.285612-05:00</FechaControl>
<Excepcion>Se generó un error al consultar la lista. Por favor intente mas tarde o contacte a su administrador.</Excepcion>
</objFosyga>
<objOfac xmlns="http://tempuri.org/">
<Id>91950</Id>
<Cedula>24944511</Cedula>
<Nombre />
<Direccion />
<Tipo />
<Programa />
<Score />
<FechaControl>2016-01-23T17:03:43.097</FechaControl>
<Lista />
<Excepcion />
<IsOfac>false</IsOfac>
</objOfac>
<objPolicia xmlns="http://tempuri.org/">
<Id>93113</Id>
<Cedula>24944511</Cedula>
<Nombre />
<IsAntecedentes>false</IsAntecedentes>
<IsRegistrado>false</IsRegistrado>
<Mensaje />
<FechaControl>2016-01-23T17:08:17.3118339-05:00</FechaControl>
<IsPolicia>false</IsPolicia>
<Excepcion>Se generó un error al consultar la lista. Por favor intente mas tarde o contacte a su administrador.</Excepcion>
</objPolicia>
<objRues xmlns="http://tempuri.org/">
<Id>91297</Id>
<TipoID />
<Nit>24944511</Nit>
<RazonSocial />
<Descripcion_Camara />
<Descripcion_Categoria_Matricula />
<Fecha_Matricula />
<IsRM>false</IsRM>
<IsRUP>false</IsRUP>
<IsESAL>false</IsESAL>
<IsRNT>false</IsRNT>
<FechaControl>2016-01-23T17:03:43.473</FechaControl>
<IsRUES>false</IsRUES>
<Excepcion />
</objRues>
<objSim xmlns="http://tempuri.org/">
<Id>92657</Id>
<Cedula>24944511</Cedula>
<NoRadicado />
<Identificador />
<FechaSolicitud />
<Estado />
<Resultado />
<DisponibleEntrega />
<Excepcion />
<FechaControl>2016-01-23T17:03:43.207</FechaControl>
<IsSim>false</IsSim>
</objSim>
<objSimit xmlns="http://tempuri.org/">
<Id>92905</Id>
<Cedula>24944511</Cedula>
<Infractor />
<Resolucion />
<FechaResolucion />
<Comparendo />
<FechaComparendo />
<Secretaria />
<Estado />
<Infraccion />
<ValorMulta />
<InteresMora />
<ValorAdicional />
<ValorPagar />
<FechaControl>2016-01-23T17:03:43.55</FechaControl>
<IsSimit>false</IsSimit>
<Excepcion />
</objSimit>
<objSisben xmlns="http://tempuri.org/">
<Id>94783</Id>
<IsSisben>true</IsSisben>
<NumeroDocumento>24944511</NumeroDocumento>
<Nombres>MARIA ISLENY</Nombres>
<Apellidos>RODAS DE FRANCO</Apellidos>
<TipoDocumento>Cédula de Ciudadanía</TipoDocumento>
<Departamento>RISARALDA</Departamento>
<Municipio>PEREIRA</Municipio>
<Area>1</Area>
<Ficha>10097</Ficha>
<Puntaje>47,86</Puntaje>
<FechaModificacion>2015/03/05</FechaModificacion>
<Estado>VALIDADO</Estado>
<FechaControl>2016-01-23T17:03:43.287</FechaControl>
<Excepcion />
</objSisben>
<objRuaf xmlns="http://tempuri.org/">
<Id>84066</Id>
<IsRuaf>true</IsRuaf>
<TipoIdentificacion>CC</TipoIdentificacion>
<Identificacion>24944511</Identificacion>
<Nombre>MARIA ISLENY RODAS DE FRANCO</Nombre>
<Sexo>FEMENINO</Sexo>
<UbicacionAfiliacion>RISARALDA - PEREIRA</UbicacionAfiliacion>
<EstadoAfiliado>ACTIVO</EstadoAfiliado>
<Administradora>NUEVA EPS SA</Administradora>
<Regimen>SALUD: CONTRIBUTIVO</Regimen>
<FechaAfiliacion>2015-08-01</FechaAfiliacion>
<TipoAfiliado>BENEFICIARIO</TipoAfiliado>
<FechaControl>2016-01-23T17:03:45.207</FechaControl>
<Observacion />
<Excepcion />
</objRuaf>
<objDisponibilidad xmlns="http://tempuri.org/">
<Fosyga>true</Fosyga>
<Sisben>true</Sisben>
<Ofac>true</Ofac>
<Policia>true</Policia>
<Rues>true</Rues>
<Sim>true</Sim>
<Simit>true</Simit>
<Contraloria>true</Contraloria>
<Onu>true</Onu>
<Ruaf>true</Ruaf>
</objDisponibilidad>
</ListasExternasFull>
and I can not get reach to consult the objRuaf/Identificacion node due to nested namespaces aguin I can help with a query to reach these nodes
Declare default XML namespace WITH XMLNAMESPACES (DEFAULT 'http://tempuri.org/'):
;WITH XMLNAMESPACES (DEFAULT 'http://tempuri.org/')
SELECT val = s.c.value('.', 'NVARCHAR(100)')
FROM #x.nodes('//objRuaf/Identificacion') AS s(c);
LiveDemo
Or:
;WITH XMLNAMESPACES ('http://tempuri.org/' AS a)
SELECT val = s.c.value('.', 'NVARCHAR(100)')
FROM #x.nodes('//a:objRuaf/a:Identificacion') AS s(c)
I am trying to load a XML document (below is an example of how I receive the files. I can read the xml, but I am unable to insert the the data into tables. Any help would be appreciative.
<xml xmlns:dt="urn:dt" xmlns:msxsl="urn:schemas-microsoft-com:xslt" dateofservice="1/1/2016 10:00" mmsid="201599999999" userid="dxxxxx9-xxx0-xxdb-xxx0-e8xxxxxxbcd" npid="dfxxxxx9-6xx0-xxxx-bxx0-exxxc1xxxxxd" surveyid="xxxxxxx-xxxa-exxx-8xxx-xxxx56xxxxefb" memberid="sqlsrfr">
<response qid="801" debug="7" value="H" element="select" />
<response qid="150" debug="8" value="Surfer" element="input" mapfield="lastname" />
<response qid="109" debug="9" value="Sequel" element="input" mapfield="firstname" />
<response qid="57" debug="11" value="01/01/1901" element="input" mapfield="dob" />
<response qid="56" debug="12" value="M" element="input" type="radio" aid="85" />
<response qid="78" debug="13" value="123 Sequel Lane" element="textarea" mapfield="addr1" />
<response qid="126" debug="39" value="Stuff" element="input" row="9" placeholder="Placeholder Desc" customtype="disabled" />
<response qid="128" debug="40" value="Stuff" element="input" row="9" placeholder="Placeholder Desc" customtype="disabled" />
<response qid="305" debug="41" value="More words" element="input" row="9" placeholder="Placeholder Desc" customtype="normal" />
<response qid="579" debug="330" value="1" element="input" type="radio" />
<response qid="580" debug="331" value="1" element="input" type="radio" />
<response qid="716" value="Words for value" calc="1" screening="1" />
<response qid="779" value="More words for value" calc="1" highriskdrug="1" />
- <surveyevents>
<event name="Event Name 2.0.3.7" time="1451495565657" count="1" />
<event name="s2" time="1451495568305" count="2" last="1451495728416" />
<event name="s3" time="1451495577298" count="1" />
<event name="s18" time="1451495601418" count="1" />
<event name="Event Name 2.0.3.7" time="1451495725279" count="1" />
<event name="Event Name 2.0.4.1" time="1453394485181" count="1" />
</surveyevents>
<recapturedata />
</xml>
Given, that you manage to read the XML into a variable, the full (de-normalized) query is this:
You will have to design three tables for MetaData, ResponseData and EventData and insert your data there.
If you need to create kind of IDs have a look on ROW_NUMBER() OVER()
btw: The declared namespaces are not used... and define the fitting datatypes yourself (I took only varchar(max) or int).
WITH XMLNAMESPACES('urn:dt' AS dt
,'urn:schemas-microsoft-com:xslt' AS msxsl)
,MetaData AS
(
SELECT #xml.value('/xml[1]/#dateofservice','varchar(max)') AS md_DateOfService
,#xml.value('/xml[1]/#mmsid','varchar(max)') AS md_MmsID
,#xml.value('/xml[1]/#userid','varchar(max)') AS md_UserID
,#xml.value('/xml[1]/#npid','varchar(max)') AS md_NpID
,#xml.value('/xml[1]/#surveyid','varchar(max)') AS md_SurveyID
,#xml.value('/xml[1]/#memberid','varchar(max)') AS md_MemberID
,#xml.query('.') AS XMLNode
)
SELECT md.md_DateOfService
,md.md_MmsID
,md.md_UserID
,md.md_NpID
,md.md_SurveyID
,md.md_MemberID
,response.value('#qid','int') AS resp_qID
,response.value('#debug','int') AS resp_Debug
,response.value('#value','varchar(max)') AS resp_Value
,response.value('#element','varchar(max)') AS resp_Element
,response.value('#row','int') AS resp_Row
,response.value('#mapfield','varchar(max)') AS resp_MapField
,response.value('#type','varchar(max)') AS resp_Type
,response.value('#aid','int') AS resp_aID
,response.value('#placeholder','varchar(max)') AS resp_Placeholder
,response.value('#customtype','varchar(max)') AS resp_CustomType
,EventRow.value('#name','varchar(max)') AS evnt_Name
,EventRow.value('#time','varchar(max)') AS evnt_Time
,EventRow.value('#count','int') AS evnt_Count
,EventRow.value('#last','varchar(max)') AS evnt_Last
FROM MetaData AS md
CROSS APPLY md.XMLNode.nodes('/xml/response') AS One(response)
CROSS APPLY md.XMLNode.nodes('/xml/surveyevents/event') AS The(EventRow)
Can you all help me for this problem?
I want to get value from following XML in sql stored procedure. I don't get vlaue if 'xsi:type="ActiveDirectoryItem"' is in tag 'anyType', and 'ActiveDirectoryItems' tag is also with URLs. How can i do to get only values?
<?xml version="1.0" encoding="utf-8" ?>
<ActiveDirectoryItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Items>
<anyType xsi:type="ActiveDirectoryItem">
<FirstName />
<MiddleInitial />
<LastName />
<DisplayName>Migrate-group</DisplayName>
<UserPrincipalName />
<PostalAddress />
<ResidentialAddress />
<Title />
<HomePhone />
<OfficePhone />
<Mobile />
<Fax />
<Email>Migrate-group#gmail.com</Email>
<Url />
<AccountName>Migrate-group</AccountName>
<DistinguishedName />
<IsAccountActive>false</IsAccountActive>
<ManagedBy />
<Manager />
<CompareType>0</CompareType>
<Description />
<Department />
<Company />
<Type />
</anyType>
</Items>
<GlobalCatalog />
</ActiveDirectoryItems>
The format i want to get is as the following:
DisplayName Email Account Name
Migrate-group Migrate-group#gmail.com Migrate-group
you can use the value keyword
Example:
DECLARE #MyXml XML = '<Root><SomeData>100</SomeData></Root>'
DECLARE #Something INT
SELECT #Something = #MyXml.value('(//Root/SomeData)[1]', 'INT')