How do I extract a specific ID in SQL from a XML column? - sqlxml

I have looked at other posts on here but I and still struggling to make it work. For example, here is my XML and I am trying retrieve just the RoleID:
<?xml version="1.0" encoding="utf-16"?>
<C_ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="aaaaaaaa-1111-1111-1111-aaaaaaaaaaaa" t_="Name" a_="U">
<U_ />
<S_>
<C_ id="bbbbbbbb-2222-2222-2222-bbbbbbbbbbbb" t_="NameMembership" a_="C">
<U_>
<F_ n_="NameId" d_="UI">
<N_>cccccccc-3333-3333-ccccccccccccccccc</N_>
</F_>
<F_ n_="RoleId" d_="UI">
<N_>dddddddd-4444-4444-ddddddddddddddddd</N_>
</F_>
</U_>
<S_ />
</C_>
</S_>
</C_>
To confirm, I am looking to retrieve the value
dddddddd-4444-4444-ddddddddddddddddd.
Any help here would be very much appreciated. FYI I am using SQL Server 2012

If you have this XML in a SQL Server variable like this:
DECLARE #SomeVar XML = N'....(your XML here)....';
then you can fetch the value of the node with the n_="RoleId" with this SQL/XQuery:
SELECT
#SomeVar.value('(/C_/S_/C_/U_/F_[#n_="RoleId"])[1]', 'varchar(100)')
UPDATE: if you have an XML column in a table, you'd approach it like this:
DECLARE #xmlTable TABLE (ID INT NOT NULL, XmlData XML);
INSERT INTO #xmlTable (ID, XmlData)
VALUES (1, N'----your XML here----');
SELECT
XC.value('(F_[#n_="RoleId"])[1]', 'varchar(100)')
FROM
#value v
CROSS APPLY
v.XmlData.nodes('/C_/S_/C_/U_') AS XT(XC)
WHERE
v.ID = 1

Related

FetchXML attribute missing

When trying to retrieve an entity from Dynamics CRM using FetchXML one of the attributes appears to be missing.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="sb_eventbooking">
<attribute name="sb_name" />
<attribute name="sb_bookeridname" /> < problem here
<attribute name="createdon" />
<atrribute ........
There are 18 attributes in the FetchXML file but when running the application only 17 are available:
And sb_bookeridname is missing. If I go into the FetchXML file and enter an attribue that I know doesn't exist then I get an error:
'sb_eventbooking' entity doesn't contain attribute with Name = 'fakeattribute'.
So the application accepts there is an attribue called 'sb_bookeridname' but I cannot get a value from it. I know there can be issues with columns with null values but other attributes don't seem to have this problem. I do use this check on all attributes and get values for all the other attributes:
if (entity.Attributes.Contains("sb_bookeridname") && entity.GetAttributeValue<String>("sb_bookeridname") != null)
{
booking.bookeridname = entity.GetAttributeValue<String>("sb_bookeridname");
}
Edit 1:
I believe you have a lookup field with schema name: sb_bookerid. When we create a lookup field, CRM automatically creates a column in the table to store the text value corresponding to lookup. So when we create a lookup field sb_bookerid, then CRM will automatically create a column in the sb_eventbooking entity by the name sb_bookeridname.
This is the reason you do not receive an error on executing FetchXML query because a column with the name exists but CRM restricts from showing its value. So if you want to retrieve the value in sb_bookerid field, please use following -
if(entity.Contains("sb_bookerid"))
{
bookeridname=((EntityReference)entity.Attributes["sb_bookerid"]).Name
}
Hope it helps.
Here is cleaner way:
bookeridname = entity.GetAttributeValue<EntityReference>("sb_bookerid")?.Name;

how to remove namespace from an existing xml subtree in oracle

I'm facing an issue with removing namespace from existing xml subtree.
For Example: I have a table with 1 field - data type xmltype. One entry is holding this xml:
<Item xmlns="http://www.w3.org/2001/XMLSchema-instance">
<Box>Blaff</Box>
<Door>Steal</Door>
<Chair>Wood</Chair>
</Item>
I would like to remove the namespace - i.e.:
<Item>
<Box>Black-box</Box>
<Door>Steal</Door>
<Chair>Wood</Chair>
</Item>
Do you have any suggestions? - I tried using the UPDATE() function with no luck.
Thank you very much for the help.
One idea is to transform it to a clob, then replace the namespace string and transform it back to xml:
with xtab as (
select xmltype('<Item xmlns="http://www.w3.org/2001/XMLSchema-instance">
<Box>Blaff</Box>
<Door>Steal</Door>
<Chair>Wood</Chair>
</Item>') my_xml from dual)
select xmltype(replace(xmltype.getclobval(my_xml),
' xmlns="http://www.w3.org/2001/XMLSchema-instance"', '')) clo
from xtab;

Multiple conditions in xpath

I am new to xquery and want to add the conditions on activityStatus as 'A' and maritalStatus as "Married" to get gender of person. I have already created query to add conditions individually but am kind of stuck in case to adding multiple conditions. Any pointers will be helpful.
Thanks in advance.
Query to get gender on the basis of Marital Status:
SELECT PersonInfo.gender_1
from personData personData,
xmltable('$personData/Person/personDataCollection/
personData[(maritalStatus=("Married"))]'
passing personData."XMLDATA" as "personData"
columns gender_1 varchar(12) path 'gender'
) PersonInfo
...and the document...
<?xml version="1.0" encoding="UTF-8"?>
<Person>
<activityStatus>A</activityStatus>
<personDataCollection>
<personData>
<personName>
<lastName>ABC</lastName>
<firstName>XYZ</firstName>
</personName>
<addressCollection>
<address>
<line1>123</line1>
<city>QWERTY</city>
<state>ASDF</state>
<postalCode>147852</postalCode>
</address>
</addressCollection>
<maritalStatus>Married</maritalStatus>
<gender>M</gender>
</personData>
</personDataCollection>
</Person>
It sounds like you just want to add a second predicate to your XPath. If that's the case then you were almost done:
$personData/Person[activityStatus="A"]/personDataCollection/personData[maritalStatus="Married"]

Can't get data with a xpath query

how could i get only the rows where the ProcedureID = 6104 in my xml database field?
<CDirData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://Fnet.ESB.Schemas.CentroDirectivo.CDirData">
<ProcedureData xmlns="">
<ProcedureId>6104</ProcedureId>
<CentroDirectivo>SGRP</CentroDirectivo>
</ProcedureData>
<SolicitudData xmlns="">
<SolicitudId>MFom635230432391710791</SolicitudId>
<Status>Iniciado</Status>
I've been trying something like
WITH XMLNAMESPACES (
'http://www.w3.org/2001/XMLSchema-instance' AS "xsi",
'http://www.w3.org/2001/XMLSchema' AS "xsd",
'http://Fnet.ESB.Schemas.CentroDirectivo.CDirData' AS "de")
SELECT [Message].value(
'(/de:CDirData/de:ProcedureData/de:ProcedureId)[1]', 'nvarch
but always returns null rows ...
Thanks in advance
The complication here is the default namespace defined at the root.
One workaround is to define your query in terms of local-name
//*[local-name()='ProcedureId' and text()='6104']

How to get child of xmlelement in sql query without its name?

In sql server xml column I have xml like this:
<Test>
<Operations>
<Operations type="OperationSend">
<OperationSend>
<ToCompanyId>1</ToCompanyId>
<Date>2011-05-01T00:00:00</Date>
</OperationSend>
</Operations>
<Operations type="OperationSell">
<OperationSell>
<ToCompanyId>33</ToCompanyId>
<Amount>12</Amount>
</OperationSell>
</Operations>
<Operations type="OperationEdit">
<OperationEdit>
<ToCompanyId>12</ToCompanyId>
<Date>2011-11-01T00:00:00</Date>
</OperationEdit>
</Operations>
</Operations>
</Test>
I need to take ToCompanyId from last operation (12). I came to something like this. What should be in ??? when there can be any operation type with ToCompanyId.
select testxml.query('(/Test/Operations/Operations)[last()]/???/ToCompanyId') from dbo.MyXmlTable
You can use *
select testxml.query('(/Test/Operations/Operations)[last()]/*/ToCompanyId').value('.', 'int')
from MyXmlTable
Put node() instead of ???
node() matches all nodes of any kind
Assuming that you have set your xml to be a variable named #x then this is how to get your 12.
select x.header.value('.', 'int')
from #x.nodes('//Test/Operations/Operations[last()]/OperationSend/ToCompanyId')
as x(header)
the query would be slightly different to get from a column of a table but the XPATH would be the same.
select testxml.query('//Test/Operations/Operations[last()]/OperationSend/ToCompanyId') from dbo.MyXmlTable

Resources