How to extract specific string part from the SQL String variable - sql

I have an Sql Variable which contains a string value and want to extract specific part from that string value,
Declare #val as nvarchar(1000),
#outval as nvarchar(1000)
set #val='<Message>
<Header>
<MessageID>000000015</MessageID>
<MessageType>QualityData</MessageType>
<Sender>Data</Sender>
<Recipient>Data1</Recipient>
<PublishedDate>2013-12-22T13:15:23</PublishedDate>
</Header>
<Body>
<ID>150105</ID>
<Data>
<Count>5</Count>
<Brix>110</Brix>
<CO2>110</CO2>
</QualityData>
</Body>
</Message>'
Now i need to extract string from to using sql query. Output should be like as below.
<Body>
<ID>150105</ID>
<Data>
<Count>5</Count>
<Brix>110</Brix>
<CO2>110</CO2>
</Data>
</Body>
any suggestion to get this format using SQL Server.

This query may help you:
Declare #val as nvarchar(1000),
#outval as nvarchar(1000),
#start as int,
#end as int,
#len as int
set #val='<Message>
<Header>
<MessageID>000000015</MessageID>
<MessageType>QualityData</MessageType>
<Sender>Data</Sender>
<Recipient>Data1</Recipient>
<PublishedDate>2013-12-22T13:15:23</PublishedDate>
</Header>
<Body>
<ID>150105</ID>
<Data>
<Count>5</Count>
<Brix>110</Brix>
<CO2>110</CO2>
</QualityData>
</Body>
</Message>'
select #val= REPLACE(#val,'<Message>','');
select #val= REPLACE(#val,'</Message>','');
SELECT #start= CHARINDEX('<Body>', #val);
SELECT #end=CHARINDEX('</Body>', #val);
select #len= LEN (#val)
SELECT #outval= SUBSTRING ( #val ,#start ,#end- #start )
print #outval

Use a substring to extract the information and patindex to find the start character and length as below:
Select Substring(#val,PATINDEX('%<body>%', #val),PATINDEX('%</body>%', #val) - PATINDEX('%<body>%', #val) + 7)

Following your statements, I added the below line to your code. I have used the SUBSTRING and CHARINDEX in my case to solve this one, and I got exactly what you are looking for. Here is my Code: SELECT SUBSTRING(#VAL, CHARINDEX('<Body>', #VAL), CHARINDEX('</QualityData>', #VAL) - CHARINDEX('<Body>', #VAL) + LEN('</QualityData>')) This worked fine for me.

Related

SSMS Obfuscation of string

I need to create a script to obfuscate some data.
The string is quite long and I need to obfuscate only some parts of it.
In the table the records are similar to this:
<?xml version="1.0" encoding="UTF-8"?><CONTRACT><IBC IBC_REF="f45f1231234ae5ac2easdasdfde5dfd" IBC_TYPE="I" TELEPHONE_1="1111111" TELEPHONE_2="11111111" MOBILE_PHONE="11111111" E_MAIL="asdasdasd#hotmail.com" SOLICITATION_MAIL="0" ARREARS_MAIL="1" MAIL_REDIRECTED="0" TITLE="Mrs" SURNAME_REGISTERED_NAME="Assadasd"
And it needs to become like this:
<?xml version="1.0" encoding="UTF-8"?><CONTRACT><IBC IBC_REF="f45f1231234ae5ac2easdasdfde5dfd" IBC_TYPE="I" TELEPHONE_1="Telephone-1" TELEPHONE_2="Telephone-2" MOBILE_PHONE="MobilePhone" E_MAIL="email-1" SOLICITATION_MAIL="0" ARREARS_MAIL="1" MAIL_REDIRECTED="0" TITLE="Mrs" SURNAME_REGISTERED_NAME="Surname"
How can I update all the rows of the table and change only some of the strings by saving the other words?
Seemingly you are working with XML strings, so I would suggest to use the SQL Server XML functionalities. Following a short example:
DECLARE #input NVARCHAR(4000) = '<?xml version="1.0" encoding="UTF-8"?><CONTRACT><IBC IBC_REF="f45f1231234ae5ac2easdasdfde5dfd" IBC_TYPE="I" TELEPHONE_1="1111111" TELEPHONE_2="11111111" MOBILE_PHONE="11111111" E_MAIL="asdasdasd#hotmail.com" SOLICITATION_MAIL="0" ARREARS_MAIL="1" MAIL_REDIRECTED="0" TITLE="Mrs" SURNAME_REGISTERED_NAME="Assadasd" /></CONTRACT>';
DECLARE #x xml = CONVERT(xml, REPLACE(#input,'encoding="UTF-8"','encoding="UTF-16"'));
SELECT #x.value('(/CONTRACT/IBC/#TELEPHONE_1)[1]', 'nvarchar(100)');
DECLARE #y xml = #x
SET #y.modify('replace value of (/CONTRACT/IBC/#TELEPHONE_1)[1] with "TELEPHONE_1"');
SELECT #y.value('(/CONTRACT/IBC/#TELEPHONE_1)[1]', 'nvarchar(100)');
SELECT #y
DECLARE #output NVARCHAR(4000) = '<?xml version="1.0" encoding="UTF-8"?>' + CONVERT(NVARCHAR(4000), #y)
SELECT #output

SQL Extract Value from XML

I have the following XML and I want to extract the FieldValue using SQL. How can I do this?
<Field Group="Annuitant">
<FieldName>Contract Number</FieldName>
<FieldValue>TR13116544</FieldValue>
</Field>
Thanks
DECLARE #xml XML=
'<Field Group="Annuitant">
<FieldName>Contract Number</FieldName>
<FieldValue>TR13116544</FieldValue>
</Field>';
--the lazy approach
SELECT #xml.value('(//FieldValue)[1]','varchar(50)')
--Better
SELECT #xml.value('(/Field/FieldValue)[1]','varchar(50)')
--This is, what you should do: Be as specific as possible...
SELECT #xml.value('(/Field/FieldValue/text())[1]','varchar(50)')
If there are - what I assume - are several <Field> elements and you need to pick the rigth one, you can do something like this:
DECLARE #name VARCHAR(100)='Contract Number';
SELECT #xml.value('(/Field[(FieldName/text())[1]=sql:variable("#name")]/FieldValue/text())[1]','varchar(50)')
Hint: Your question is not very clear, that needs a lot of guessing on my side. For your next question I ask you to be more specific.
Sample code:
DECLARE #MyXML XML
SET #MyXML ='<SampleXML>
<Fruits>
<Fruits1>Apple</Fruits1>
<Fruits2>Pineapple</Fruits2>
</Fruits>
</SampleXML>'
SELECT
a.b.value('Fruits[1]/Fruits1[1]','varchar(10)') AS Fruits1,
a.b.value('Fruits[1]/Fruits2[1]','varchar(10)') AS Fruits2
FROM #MyXML.nodes('SampleXML') a(b)
In oracle you can do the following:
WITH TABL (FIELD) AS (
select xmltype('<Field Group="Annuitant">
<FieldName>Contract Number</FieldName>
<FieldValue>TR13116544</FieldValue>
</Field>') from dual
)
SELECT
EXTRACTVALUE(FIELD,'/Field/FieldName') AS FIELDNAME,
EXTRACTVALUE(field,'/Field/FieldValue') AS FieldValue
FROM TABL ;

SQL - Define/Modify XML with variables

I'm trying to define an XML variable with VARCHAR characters inside of it...
Example
DECLARE #number nvarchar(10);
SET #number = '10'
DECLARE #xml XML;
SET #xml =
'
<Root>
<Node> Hello {sql:variable("#number")} </Node>
</Root>
'
However, the problem is that you can only set xml variables to string literals. Is there any way of doing this? Thanks!
Not sure why you want to do this. Use + to concatenate the variable inside the string then assign it to xml varibale
DECLARE #number NVARCHAR(10);
SET #number = '10'
DECLARE #xml XML;
SET #xml = '
<Root>
<Node> Hello ' + Isnull(#number,'') + ' </Node>
</Root>
'
To view the xml
select #xml
Result :
<Root>
<Node> Hello 10 </Node>
</Root>
DECLARE #number nvarchar(10) = '10';
DECLARE #xml XML = N'';
SELECT #xml = #xml.query('
<Root>
<Node>Hello {sql:variable("#number")}</Node>
</Root>
');
SELECT #xml;
/*
<Root>
<Node>Hello 10</Node>
</Root>
*/
In my eyes the existing answers (upvoted and accepted) are no good paths to go. One should (almost) never create XML via string concatenation...
Why not the simple way? Let the XML-engine do the hard work!
DECLARE #number nvarchar(10);
SET #number = '10'
DECLARE #xml XML=(SELECT 'Hello ' + #number FOR XML PATH('Node'),ROOT('Root'),TYPE);
SELECT #xml;
Returns
<Root>
<Node>Hello 10</Node>
</Root>
Just imagine, your (string!) variable includes some text with forbidden characters (><& or qoutes or one of the many special / far east / whatever characters)... Using FOR XML ... will implicitly do all the escaping for you...
One side effect: If your variable is NULL you will not get a NULL for all, but a valid XML with an empty node:
<Root>
<Node />
</Root>

Convert Plain Text to HTML

I am having HTML code text as
select prd_desc from prd_mst
prd_desc
------------------------------------------------
<u>hello</u> <font color="#cc0000">dfgfdg</font>
How can i make it format in a HTML as 'hello...'
I am using replace function for all those special HTML characters or sqlserver has some shortcut, function for it.
You can use the XML datatype for this.
If you cast your value to XML that will give you a XML fragment that consists of one text element only. Extract that value using the value() function and you have a string that is not entitized.
select cast(p.prd_desc as xml).value('text()[1]', 'nvarchar(max)') as prd_desc
from dbo.prd_mst as p
Result:
prd_desc
-------------------------------------------------
<u>hello</u> <font color="#cc0000">dfgfdg</font>
Try this,
create FUNCTION udf_HtmlDecode
(
#UnDecoded as varchar(max)
)
RETURNS varchar(500)
AS
BEGIN
--declare #UnDecoded as varchar(500);
--set #UnDecoded = 'xvfxv <u>cbgdfgd</u> <font color="#cc0000">dfgfdg</font> <b>gdfgdf</b><br>';
DECLARE #Encoded as varchar(max)
--order is important here. Replace the amp first, then the lt and gt.
--otherwise the &lt will become &lt;
SELECT #Encoded = Replace(
Replace(
Replace(
Replace(#UnDecoded,'&','&'),
'<', '<'),
'>', '>'),
'"','"')
RETURN #Encoded
--select #Encoded
END
then execute
select dbo.udf_HtmlDecode('<u>hello</u> <font color="#cc0000">dfgfdg</font>')
will return
<u>hello</u> <font color="#cc0000">dfgfdg</font>

T-SQL Code to edit XML

In the XML text below, I want to write an update script to modify the date part 2013-12-30T04:30:00.000+00:00 with dateadd(minute, 2, getdate())
How do I get the format as represented in the XML text.
What would be the best way to concatenate the date?
<ScheduleDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<StartDateTime xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">2013-12-30T04:30:00.000+00:00</StartDateTime>
<WeeklyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">
<WeeksInterval>1</WeeksInterval>
<DaysOfWeek>
<Sunday>true</Sunday>
<Monday>true</Monday>
<Tuesday>true</Tuesday>
<Wednesday>true</Wednesday>
<Thursday>true</Thursday>
<Friday>true</Friday>
<Saturday>true</Saturday>
</DaysOfWeek>
</WeeklyRecurrence>
</ScheduleDefinition>
This:-
declare #xml varchar(max)
set #xml='<ScheduleDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<StartDateTime xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">2013-12-30T04:30:00.000+00:00</StartDateTime>
<WeeklyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">
<WeeksInterval>1</WeeksInterval>
<DaysOfWeek>
<Sunday>true</Sunday>
<Monday>true</Monday>
<Tuesday>true</Tuesday>
<Wednesday>true</Wednesday>
<Thursday>true</Thursday>
<Friday>true</Friday>
<Saturday>true</Saturday>
</DaysOfWeek>
</WeeklyRecurrence>
</ScheduleDefinition>'
declare #pos int
set #pos=charindex('</StartDateTime>',#xml)
select left(#xml,#pos-30)+
convert(varchar(23),dateadd(minute,2,sysutcdatetime()),126)+'+00:00'+
substring(#xml,#pos,datalength(#xml))
Returns:-
<ScheduleDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<StartDateTime xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">2014-02-19T21:27:36.348+00:00</StartDateTime>
<WeeklyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">
<WeeksInterval>1</WeeksInterval>
<DaysOfWeek>
<Sunday>true</Sunday>
<Monday>true</Monday>
<Tuesday>true</Tuesday>
<Wednesday>true</Wednesday>
<Thursday>true</Thursday>
<Friday>true</Friday>
<Saturday>true</Saturday>
</DaysOfWeek>
</WeeklyRecurrence>
</ScheduleDefinition>
It uses charindex() to find a consistent piece of text (</StartDateTime>) in your xml. It then uses left() to cut off the start of the xml (truncating off the current date). It then uses sysutcdatetime() to get the current time of your server expressed in UTC time (so that later a consistent timezone offset of +00:00 can be applied). It then uses convert() with a style of 126 to convert the time into the format required for your xml. It then uses substring() and datalength() to add the end of your xml (the length does not need to be exact).
Hopefully, this will give you some ideas about how to go about cutting up your xml to substitute the date that you want.
DATETIMEOFFSET datatype and XML.modify(). I would not recommend treating XML as text if there is a way to do it using XML. Your namespaces make it a little tricky. This works on SQL Server 2008 R2.
DECLARE #XML XML
DECLARE #NEWVALUE DATETIMEOFFSET
set #XML='<ScheduleDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<StartDateTime xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">2013-12-30T04:30:00.000+00:00</StartDateTime>
<WeeklyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices">
<WeeksInterval>1</WeeksInterval>
<DaysOfWeek>
<Sunday>true</Sunday>
<Monday>true</Monday>
<Tuesday>true</Tuesday>
<Wednesday>true</Wednesday>
<Thursday>true</Thursday>
<Friday>true</Friday>
<Saturday>true</Saturday>
</DaysOfWeek>
</WeeklyRecurrence>
</ScheduleDefinition>'
;WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices' AS X)
SELECT #NEWVALUE = TableAlias.FieldAlias.value('(X:StartDateTime/text())[1]', 'DATETIMEOFFSET') FROM #XML.nodes('//ScheduleDefinition') AS TableAlias(FieldAlias)
SET #NEWVALUE = DATEADD(MINUTE,2,#NEWVALUE)
DECLARE #FORMAT VARCHAR(max) = CONVERT(VARCHAR(MAX),#NEWVALUE,126)
SET #XML.modify('
declare namespace x="http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices";
replace value of (/ScheduleDefinition/x:StartDateTime[1]/text())[1]
with sql:variable("#FORMAT")
')
SELECT #XML