SELECT only specific value from XML column in SQL - sql

Running the following TSQL
SELECT Name FROM Category
returns these results as the column in SQL is of xml data type.
1 <locale en-US="Abstract" />
2 <locale en-US="African" />
3 <locale en-US="Americana" />
I'd like to get a result set like:
1 Abstract
2 African
3 Americana
How can I do this?

You can try to use the .value function
SELECT Name.value('(/locale/#en-US)[1]','varchar(20)')
from Category
sqffiddle

Related

WHERE JSON_Value Dynamically

I am working with the JSON_VALUE function and I need a kind of dynamic query
I have a column called Criteria and sometimes it has 1 value but sometimes it has 2 or 3 vales like:
Example of 1 value: $.IRId = 1
Example of 2 values: $.IROwner = 'james.jonson#domain.com' AND DaysTillDue < 10
So in order to read the values from a JSON column and taking the Criteria column I am using this logic:
DECLARE #CriteriaValue int
,#CriteriaStatement VARCHAR(50)
SELECT #CriteriaValue=SUBSTRING(Criteria, CHARINDEX('=',Criteria)+1, len(Criteria)) FROM #SubscriptionCriteria;
SELECT #CriteriaStatement= SUBSTRING(Criteria,0, CHARINDEX('=',Criteria)) FROM #SubscriptionCriteria;
SELECT #CriteriaValue,#CriteriaStatement
SELECT *
FROM [SAAS].[ObjectEvent]
WHERE
JSON_VALUE(JSONMessageData, #CriteriaStatement) = #CriteriaValue
That SQL code is taking only the Criteria Column with only 1 value ($.IRId = 1), but the idea is to have something that reads the criteria no matter the different filters and apply them into the final query. The idea I have is that the query would look like this:
SELECT *
FROM [SAAS].[ObjectEvent]
WHERE
JSON_VALUE(JSONMessageData, #CriteriaStatement1) = #CriteriaValue1 ADN JSON_VALUE(JSONMessageData, #CriteriaStatement2) = #CriteriaValue2 AND
JSON_VALUE(JSONMessageData, #CriteriaStatement3) = #CriteriaValue3
ETC
Any suggestion?

How to UPDATE value for fields inside a xml column : SQL Server 2012

I have a sql table let's say Criteria, having a xml column ResultCriteria.
Criteria
CriteriaID CriteriaName ResultCriteria
1 Criteria1 <Results>.... </Results>
Value for ResultCriteriaColumn :
<Results>
<Result Name=Result1 Title=SearchResultTile1 SortOrder=Asc>
<Result Name=Result2 Title=SearchResultTile2>
<Result Name=Result3 Title=SearchResultTile3 Parent=XYZ>
</Results>
And a configuration table where Titles for Result columns are stored like:-
ResultColumnNameID ResultColumnName Title
1 Result1 TitleA
2 Result2 TitleB
Now i have to update(Change name from a config table) ResultCriteria for every row through a sql script.
I have managed to fetch data in two table variable like
ResultLookup
ResultColumnName Title
Result1 Title1
Result2 Ttile3
TempTableToUpdate (i created this for first row, so that i can repeat this logic on every row by using cursor.)
CriteriaRow1 ResultXML
Criteria1 <Name='Result1' Title='Result1Title' Parent='ABC'/>
Criteria1 <Name='Result2' Title='Result2Title' Sort='ASC'/>
Criteria1 <Name='Result3' Title='Result3Title' Parent='XYZ'/>
PS: ResultColumnName is unique
Now i just have to replace Title from ResultLookup(Table 1) to ResultXML, convert everything back to Xml. Finally update this new xml into row 1 of Criteria table.
Could someone please suggest how this can be achieved in SQL Server 2012 ?

Find specific strings All Position from large string

I want to find all position of 'LIID' string into 'DATASTRING' column using which help to find all LLID values.
DATASTRING Column contains MIXED data its not valid XML file.
Query :
select id , DATASTRING from mixdatatable
Output :
id DATASTRING
1 ABC XYZ IS 1 ..
<ObjectValue /><CP /><SIProps ST="4" PL="False" PLS="" />
<STI_SummaryActiveProblemsField LIID="cdbd7044-ccde-11db-8cba-df0a56d89593" IID="37742a5f-7998-4715-8d43-0d7a19284d44" IR="True" RW="1">
<HD Title="Active Problems" /><ObjectValue />
<CP><PosReplace /><NegReplace /></CP><SIProps ST="4" PL="False" PLS="" />
-<STI_DxItem IID="d85c91e7-703f-4f8c-9a38-961fb2d14828" RW="1" LIID="03e4da86-d57c-408e-9479-b6fb97cc9a60"><HD Title=" unspecified "/>
<STI_US><ObjectValue><TextValue><![CDATA[
]]></TextValue></ObjectValue><CP />
<LIID='71194038-8ffb-488b-8af5-5f1f1a679115'>
<SIProps ST="1" SS=" " PL="False" PLS="" />
</STI_US> AAAAAA
979816816/881783683618317381-817
I want to find all LIID values. LLID values lenth are '36' eg.'cdbd7044-ccde-11db-8cba-df0a56d89593'
Expected Output :
ID LLID
1 cdbd7044-ccde-11db-8cba-df0a56d89593
1 03e4da86-d57c-408e-9479-b6fb97cc9a60
1 71194038-8ffb-488b-8af5-5f1f1a679115
PostgreSQL version 8.3
Note : i dont have acess to create function or procedure.
select id, unnest(regexp_matches(datastring,'LIID=[''"]([0-9a-f-]+)','g'))
from mixdatatable
Test on sqlfiddle.com

XML Data into Row Selection

I have a single field in a DB which contains columns of data, but in an continuous string of XML.
I want to extract the data from the XML, and return as normal columns.
There could be multiple rows of data within this single field.
Here are 2 real examples of data in this field
Example 1:
<DocumentElement>
<AuditTrailDetail>
<TableName>order_header_total</TableName>
<RowID>837</RowID>
<AuditType>Edit</AuditType>
<FieldName>oht_foreign_net</FieldName>
<ValueFrom>65.1600</ValueFrom>
<ValueTo>115.1600</ValueTo>
<EntityName />
<DisplayName />
<Identifier />
</AuditTrailDetail>
<AuditTrailDetail>
<TableName>order_line_item</TableName>
<RowID>2442</RowID>
<AuditType>Edit</AuditType>
<FieldName>oli_qty_required</FieldName>
<ValueFrom>1.0000</ValueFrom>
<ValueTo>2.0000</ValueTo>
<EntityName />
<DisplayName />
<Identifier>61 - test</Identifier>
</AuditTrailDetail>
</DocumentElement>
Example 2:
<DocumentElement>
<AuditTrailDetail>
<TableName>order_line_item</TableName>
<RowID>2446</RowID>
<AuditType>Edit</AuditType>
<FieldName>oli_description</FieldName>
<ValueFrom>2 Ply Tissue Masks</ValueFrom>
<ValueTo>2 Ply Tissue Masksdd</ValueTo>
<EntityName />
<DisplayName />
<Identifier>D/D170 - 2 Ply Tissue Masksdd</Identifier>
</AuditTrailDetail>
</DocumentElement>
For Example 1, I'd like to return 2 rows as below:
For Example 2 there is one row, and I'd like it as below:
The fields in the table are:
owat_id
owat_audit_type
owat_record_id
owat_record_type
owat_datetime
owat_ud_id
owat_details
The XML data is within owat_details.
Assume the table name is Audit_Trail.
How can I do this directly in the SQL query?
Thank you to Johnie Karr
I have got this working using XQuery.
I have to do 2 queries and union them together to get the 2 separate elements in one field as separate rows. I'm sure there is a cleaner solution, but this works.
Thank you very much :)
SELECT
AuditTrail.owat_record_type,
AuditTrail.owat_audit_type,
AuditTrail.owat_datetime as 'Audit Date',
user_detail.ud_username as 'User',
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/TableName)[1]','varchar(50)') AS TableName,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/RowID)[1]','varchar(50)') AS RowID,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/FieldName)[1]','varchar(50)') AS FieldName,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/ValueFrom)[1]','varchar(50)') AS ValueFrom,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/ValueTo)[1]','varchar(50)') AS ValueTo,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/Identifier)[1]','varchar(50)') AS Identifier
FROM
(select
orderwise_audit_trail.owat_id,
orderwise_audit_trail.owat_audit_type,
orderwise_audit_trail.owat_record_id,
orderwise_audit_trail.owat_record_type,
orderwise_audit_trail.owat_datetime,
orderwise_audit_trail.owat_ud_id,
convert(xml, orderwise_audit_trail.owat_details) as owat_details
from
orderwise_audit_trail) as AuditTrail
left join user_detail on user_detail.ud_id = AuditTrail.owat_ud_id
Where AuditTrail.owat_details is not NULL
and (AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/TableName)[1]','varchar(50)')) is not null
UNION ALL
SELECT
AuditTrail.owat_record_type,
AuditTrail.owat_audit_type,
AuditTrail.owat_datetime as 'Audit Date',
user_detail.ud_username as 'User',
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/TableName)[2]','varchar(50)') AS TableName,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/RowID)[2]','varchar(50)') AS RowID,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/FieldName)[2]','varchar(50)') AS FieldName,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/ValueFrom)[2]','varchar(50)') AS ValueFrom,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/ValueTo)[2]','varchar(50)') AS ValueTo,
AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/Identifier)[2]','varchar(50)') AS Identifier
FROM
(select
orderwise_audit_trail.owat_id,
orderwise_audit_trail.owat_audit_type,
orderwise_audit_trail.owat_record_id,
orderwise_audit_trail.owat_record_type,
orderwise_audit_trail.owat_datetime,
orderwise_audit_trail.owat_ud_id,
convert(xml, orderwise_audit_trail.owat_details) as owat_details
from
orderwise_audit_trail) as AuditTrail
left join user_detail on user_detail.ud_id = AuditTrail.owat_ud_id
Where AuditTrail.owat_details is not NULL
and (AuditTrail.owat_details.value('(/DocumentElement/AuditTrailDetail/TableName)[2]','varchar(50)')) is not null
order by 1, 2, 3, 4

xmlquery returns all values as one long line instead of separate entities

I am trying to query the telephone numbers from the following xml file
<xmlPhoneEntity>
<TelephoneEntity>
<number>123</number>
</TelephoneEntity>
<TelephoneEntity>
<number>456</number>
</TelephoneEntity>
<TelephoneEntity>
<number>789</number>
</TelephoneEntity>
</xmlPhoneEntity>
This XML is located in my DB - the table looks like this
id customer_id telephone blabla
1 111 xmlfile
2 222 xmlfile
etc
My sql query looks like this -
select xmlserialize(xmlquery('/xmlPhoneEntity/TelephoneEntity/number/text()
passing telephone"
the response: 123456789
I tried using /nodes() instead of /text() and the result is the same.
How do I separate the values ?