How to get value from XML in stored procedure? - sql

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

Related

Select data using WHERE condition on XML data column in SQL table

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.

Creating XML from MSSQL

How can I create the following XML from MS SQL?
I've looked and google and cant see for my specific example as below, thanks.
This would be from an SQL query using XML PATH in some manner.
<message>
<header date="15/07/2016" userid="QUOTEJOB">
<schema name="TKJobLoaderSchema" version="1.0" />
<source system="" product="" productversion="" />
<destination system="" product="" productversion="" />
</header>
<body>
<jobs>
<job action="jmCreate" company="02" contract="QW" description="test job" job_type="02" priority="5" created_by="QUOTEJOB">
<job_lines>
<job_line line_no="1" line_type="SOR" code="AQW" quantity="1916.5" />
</job_lines>
<job_narratives>
<job_narrative id="2" narrative="4678f874-314c-4584-99e3-c69e3af71999" />
</job_narratives>
<job_property company="02" ref="02363" />
</job>
</jobs>
</body>
</message>
Assuming, that every value is 1:1 your given sample can be created like the following (replace the literals with your actual column names, variables, whatever):
SELECT {d'2016-07-15'} AS [header/#date]
,'QUOTEJOB' AS [header/#userid]
,'TKJobLoaderSchema' AS [header/schema/#name]
,'1.0' AS [header/schema/#version]
,'' AS [header/source/#system]
,'' AS [header/source/#product]
,'' AS [header/source/#productversion]
,'' AS [header/destination/#system]
,'' AS [header/destination/#product]
,'' AS [header/destination/#productversion]
,'jmCreate' AS [body/jobs/job/#action]
,'02' AS [body/jobs/job/#company]
--more attributes of <job>
,1 AS [body/jobs/job/job_lines/job_line/#line_no]
--more attributes of <job_line>
,2 AS [body/jobs/job/job_narratives/job_narrative/#id]
--more attributes of <job_narrative>
,'02' AS [body/jobs/job/job_property/#company]
,'02363' AS [body/jobs/job/job_property/#ref]
FOR XML PATH('message')
The result
<message>
<header date="2016-07-15T00:00:00" userid="QUOTEJOB">
<schema name="TKJobLoaderSchema" version="1.0" />
<source system="" product="" productversion="" />
<destination system="" product="" productversion="" />
</header>
<body>
<jobs>
<job action="jmCreate" company="02">
<job_lines>
<job_line line_no="1" />
</job_lines>
<job_narratives>
<job_narrative id="2" />
</job_narratives>
<job_property company="02" ref="02363" />
</job>
</jobs>
</body>
</message>

Selecting values out of XML with SQL Server 2012 with nested namespaces

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)

How to remove xml nodes without attribute in Sql Server

What is the correct way to remove all child nodes of the root node with a missing attribute from an xml field in Sql Server 2008?
My Xml looks like this, I want to remove all the child nodes of <root> that don't have the ln attribute specified
<root>
<title />
<title />
<questionphrase ln="nl">
<xhtml />
</questionphrase>
<questionphrase ln="en">
<xhtml />
</questionphrase>
<information ln="nl">
<xhtml />
</information>
<information ln="en">
<xhtml />
</information>
<title />
<title ln="en">
value
</title>
<label ln="en">
value
</label>
<title />
<title />
</root>
After the delete the xml should look like this
<root>
<questionphrase ln="nl">
<xhtml />
</questionphrase>
<questionphrase ln="en">
<xhtml />
</questionphrase>
<information ln="nl">
<xhtml />
</information>
<information ln="en">
<xhtml />
</information>
<title ln="en">
value
</title>
<label ln="en">
value
</label>
</root>
Try this:
DECLARE #xml XML = '....'
SET #xml.modify('delete //root/*[not(#ln)]')
SQL FIDDLE DEMO

sp_xml_preparedocument go with error "Only one top level element is allowed in an XML document"

I'am trying to execute sp_xml_preparedocument and geting error "Only one top level element is allowed in an XML document"
my T-SQL commands:
DECLARE #aa XML
DECLARE #idoc int
SET #aa =(select * from db_name for xml auto, xmldata)
#aa now is
<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes" name="Schema7">
<ElementType name="Person" content="empty" model="closed">
<AttributeType name="preson_id" dt:type="i4" />
<AttributeType name="Name" dt:type="string" />
<AttributeType name="Surname" dt:type="string" />
<AttributeType name="guid" dt:type="uuid" />
<AttributeType name="version" dt:type="bin.base64" />
<attribute type="preson_id" />
<attribute type="Name" />
<attribute type="Surname" />
<attribute type="guid" />
<attribute type="version" />
</ElementType>
</Schema>
<Person xmlns="x-schema:#Schema7" preson_id="1" Name="Иван" Surname="Иванов" guid="2E739E87-3CA4-4ED8-ADD0-8B59957668B8" version="AAAAAAAAB9E=" />
<Person xmlns="x-schema:#Schema7" preson_id="2" Name="Николай" Surname="Николаев" guid="BDC41C59-D70F-4B70-954E-4918B9516AF8" version="AAAAAAAAB9I=" />
<Person xmlns="x-schema:#Schema7" preson_id="3" Name="Максим" Surname="Максимов" guid="740E57F3-56BA-48B8-92AF-978D7B1D2712" version="AAAAAAAAB9M=" />
EXEC sp_xml_preparedocument #idoc OUTPUT, #aa
The XML parse error 0xc00ce555 occurred on line number 1, near the XML text ""
Msg 6602, Level 16, State 2, Procedure sp_xml_preparedocument, Line 1
The error description is 'Only one top level element is allowed in an XML document
I'am new in this, and i need help)))
An one more question - How parse timestamp type?
if i use
SET #aa =(select * from db_name for xml elements, root('root'), type)
sp_xml_preparedocument works fine, OPENXML returns all values of my db_table, but timestamp values looks not the same as were..
Sorry for my bad English
SELECT #aa returns
<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes" name="Schema7">
<ElementType name="Person" content="empty" model="closed">
<AttributeType name="preson_id" dt:type="i4" />
<AttributeType name="Name" dt:type="string" />
<AttributeType name="Surname" dt:type="string" />
<AttributeType name="guid" dt:type="uuid" />
<AttributeType name="version" dt:type="bin.base64" />
<attribute type="preson_id" />
<attribute type="Name" />
<attribute type="Surname" />
<attribute type="guid" />
<attribute type="version" />
</ElementType>
</Schema>
<Person xmlns="x-schema:#Schema7" preson_id="1" Name="Иван" Surname="Иванов" guid="2E739E87-3CA4-4ED8-ADD0-8B59957668B8" version="AAAAAAAAB9E=" />
<Person xmlns="x-schema:#Schema7" preson_id="2" Name="Николай" Surname="Николаев" guid="BDC41C59-D70F-4B70-954E-4918B9516AF8" version="AAAAAAAAB9I=" />
<Person xmlns="x-schema:#Schema7" preson_id="3" Name="Максим" Surname="Максимов" guid="740E57F3-56BA-48B8-92AF-978D7B1D2712" version="AAAAAAAAB9M=" />
An XML document must have one root element only - see W3C specification.
Thus in you case if Schema is the root element you cannot add the Person elements at the end
Make sure that there is no duplicate entries for the record that you are trying to get