Count the occurrences of substring - html

I have a html string:
<img src="aaa"/>blah blah <img src="333"/>long content
I just want to count the number of img tag occurrences in the string field.
I know i can use CLR in SQL server or i could use something like HtmlAgilityPack to parse the string, but i have no permission to install CLR and want a more effective way.
So is there any way to use normal SQL to achieve this.

try this
Declare #string varchar(1000)
Set #string = '<img src="aaa"/>blah blah <img src="333"/>long content<img'
select len(#string) - len(replace(#string, '<img', 'xxx'))

One dirty trick you can use is,
select (len(myCol) - len(replace(myCol, '<img ', ''))) / len('<img ') AS imgCount
from myTable

Related

Extracting a substring after finding a different substring

I've been playing around with Substring, left, right, charindex and can't quite get this to work
If this is the value in column name 'Data' (this is all one line)
{"email":{"RecipientId":"usertest","RecipientEmail":"test#test.com","Subject":"This is a test subject heading","RecipientSubject":"A recipient subject"}}
How do I do a SELECT statement to find the 'Subject' heading and then get the data 'This is a test subject'? The Subject value is different for every record so I just can't look for 'This is a test subject'.
So the end result should be This is a test subject for that SELECT result
The following query should do what you want:
declare #string varchar(max);
set #string = '{"email":{"RecipientId":"usertest","RecipientEmail":"test#test.com","Subject":"This is a test subject heading","RecipientSubject":"A recipient subject"}}';
select substring(#string,charindex('"Subject":',#string)+11,charindex('"RecipientSubject"',#string)-charindex('"Subject"',#string)-13);
The plain and easy-cheesy approach is this:
SELECT SUBSTRING(
t.YourString
,A.StartPosition
,CHARINDEX('"'
,t.YourString
,A.StartPosition+1) - A.StartPosition
)
FROM #dummyTable t
CROSS APPLY(SELECT CHARINDEX('"Subject":"',t.YourString)+11) A(StartPosition)
I use APPLY to calculate a value and use it like you'd use a variable. The idea is: Find the starting point and look for the closing quote from there. But this will break, whenever the content includes an (escaped) quote like in
"Subject":"This is \"quoted\" internally"
A more generic approach
Starting with v2016 JSON-support was introduced. With this (or a higher) version this is really simple:
Use this mockup-table for testing
DECLARE #dummyTable TABLE (YourString VARCHAR(1000));
INSERT INTO #dummyTable VALUES('{"email":{"RecipientId":"usertest","RecipientEmail":"test#test.com","Subject":"This is a test subject heading","RecipientSubject":"A recipient subject"}}');
--The OPENJSON-method will read this for you:
SELECT JsonContent.*
FROM #dummyTable t
CROSS APPLY OPENJSON(t.YourString,'$.email')
WITH(RecipientId VARCHAR(100)
,RecipientEmail VARCHAR(100)
,[Subject] VARCHAR(100)
,RecipientSubject VARCHAR(100)) JsonContent;
But with a lower version you will need to trick this out. It is the easiest, to tranform JSON to attribute centered XML like here:
<email RecipientId="usertest" RecipientEmail="test#test.com" Subject="This is a test subject heading" RecipientSubject="A recipient subject" />
We can achieve this by some string methods and I must warn you, that there are several pit-falls with forbidden characters and other stuff... Just try it out:
SELECT Casted.ToXml.value('(/email/#RecipientId)[1]','varchar(1000)') AS RecipientId
,Casted.ToXml.value('(/email/#RecipientEmail)[1]','varchar(1000)') AS RecipientEmail
,Casted.ToXml.value('(/email/#Subject)[1]','varchar(1000)') AS [Subject]
,Casted.ToXml.value('(/email/#RecipientSubject)[1]','varchar(1000)') AS RecipientSubject
,Casted.ToXml.query('.') LookHowThisWasTransformed
FROM #dummyTable t
CROSS APPLY
(
SELECT CAST(CONCAT('<email '
,REPLACE(REPLACE(REPLACE(REPLACE(t.YourString,'{"email":{"',''),'}}',''),'","','" '),'":"',' ="')
,' />') AS XML)
) Casted(ToXml);

unescape diactrics in \u0 format (json) in ms sql (SQL Server)

I'm getting json file, which I load to Azure SQL databese. This json is direct output from API, so there is nothing I can do with it before loading to DB.
In that file, all Polish diactircs are escaped to "C/C++/Java source code" (based on: http://www.fileformat.info/info/unicode/char/0142/index.htm
So for example:
ł is \u0142
I was trying to find some method to convert (unescape) those to proper Polish letters.
In worse case scenario, I can write function which will replace all combinations
Repalce(Replace(Replace(string,'\u0142',N'ł'),'\u0144',N'ń')))
And so on, making one big, terrible function...
I was looking for some ready functions like there is for URLdecode, which was answered here on stack in many topics, and here: https://www.codeproject.com/Articles/1005508/URL-Decode-in-T-SQL
Using this solution would be possible but I cannot figure out cast/convert with proper collation and types in there, to get result I'm looking for.
So if anyone knows/has function that would make conversion in string for unescaping that \u this would be great, but I will manage to write something on my own if I would get right conversion. For example I tried:
select convert(nvarchar(1), convert(varbinary, 0x0142, 1))
I made assumption that changing \u to 0x will be the answer but it gives some Chinese characters. So this is wrong direction...
Edit:
After googling more I found exactly same question here on stack from #Pasetchnik: Json escape unicode in SQL Server
And it looks this would be the best solution that there is in MS SQL.
Onlty thing I needed to change was using NVARCHAR instead of VARCHAR that is in linked solution:
CREATE FUNCTION dbo.Json_Unicode_Decode(#escapedString nVARCHAR(MAX))
RETURNS nVARCHAR(MAX)
AS
BEGIN
DECLARE #pos INT = 0,
#char nvarCHAR,
#escapeLen TINYINT = 2,
#hexDigits TINYINT = 4
SET #pos = CHARINDEX('\u', #escapedString, #pos)
WHILE #pos > 0
BEGIN
SET #char = NCHAR(CONVERT(varbinary(8), '0x' + SUBSTRING(#escapedString, #pos + #escapeLen, #hexDigits), 1))
SET #escapedString = STUFF(#escapedString, #pos, #escapeLen + #hexDigits, #char)
SET #pos = CHARINDEX('\u', #escapedString, #pos)
END
RETURN #escapedString
END
Instead of nested REPLACE you could use:
DECLARE #string NVARCHAR(MAX)= N'\u0142 \u0144\u0142';
SELECT #string = REPLACE(#string,u, ch)
FROM (VALUES ('\u0142',N'ł'),('\u0144', N'ń')) s(u, ch);
SELECT #string;
DBFiddle Demo

MySQL - How to get the string next after to a symbol?

For Example: word_word_#_word_word
i want to replace third word from left after the #_ by someother word, i dont know the exact string from the database. So how can i write sql query for this.
use replace:
select SELECT REPLACE('word_word_#_word_word', '#_word', '#_otherword');
Use Stuff function
Declare #String varchar(200)='word_word_#_word_word'
SELECT #String AS GivenString,STUFF(#String,(CHARINDEX('#_',#String)+2),0,'Otherword'+'_') AS Otherword_Column
OutPut
GivenString Otherword_Column
------------------------------------------------------
word_word_#_word_word word_word_#_Otherword_word_word

The argument 1 of the XML data type method "modify" must be a string literal

Hi i am getting the string literal error when i am trying to add an attribute to the child node. How can i modify my code in order to add an attribute successfully.
declare #count int=(select mxGraphXML.value('count(/mxGraphModel/root/Cell/#Value )','nvarchar') from TABLE_LIST
where Table_ListID=1234 )
declare #index int=1;
while #index<=#count
begin
declare #Value varchar(100)= #graphxml.value('(/mxGraphModel/root/Cell/#Value )[1]','nvarchar');
SET #graphxml.modify('insert attribute copyValueID {sql:variable("#Value ")}
as first into (/mxGraphModel/root/Cell)['+convert(varchar,#index)+']');
end
set #index=#index+1;
end
You're using the addition operator where you should be using the CONCAT function. So
'insert attribute copyValueID {sql:variable("#Value ")}
as first into (/mxGraphModel/root/Cell)['+convert(varchar,#index)+']'
is being coerced into a number. Try:
CONCAT('insert attribute copyValueID {sql:variable("#Value ")}
as first into (/mxGraphModel/root/Cell)[',convert(varchar,#index),']')
instead.
Adam, you can do it in Microsoft T-SQL like this:
declare #sql nvarchar(max)
set #sql = 'set #myxml.modify(''
insert (
attribute scalableFieldId {sql:variable("#sf_id")},
attribute myTypeId {sql:variable("#my_type_id")}
) into (/VB/Condition/Field[#fieldId=sql:variable("#field_id")
and #fieldCode=sql:variable("#field_code")])['+
cast(#instance as varchar(3))+']'')'
exec sp_executesql
#sql
,N'#myxml xml output, #field_code varchar(20),
#field_id varchar(20), #sf_id int, #my_type_id tinyint'
,#myxml = #myxml output
,#field_code = #field_code
,#field_id = #field_id
,#sf_id = #sf_id
,#my_type_id = #my_type_id
See what I've done here? It's just a clever usage of Dynamic SQL to overcome Microsoft's moronic limitation of "string literal error".
IMPORTANT NOTE: yes, you can MOSTLY do this by using sql:variable() in SOME places BUT good luck trying to use it in the node number qualifier inside the square brackets! You can't do this without Dynamic SQL by design!
The trick is not mine actually, I got the idea from https://www.opinionatedgeek.com/Snaplets/Blog/Form/Item/000299/Read after banging my head against the wall for a while.
Feel free to ask questions if my sample does not work or something is not clear.

MySQL Query: Trim a string in an entry from some start string to some end string?

I want to write a query to remove '' strings from an entry up until '>' characters.
Say I have:
<a href='somesite'>Text Link</a>
The result should be:
Text Link</a>
You can try this:
SET #tmp = "<a href='somesite'>Text Link</a>";
SELECT RIGHT(#tmp,LENGTH(#tmp)-LOCATE('>',#tmp));
Note: LOCATE finds the first occurrence of substring; that may or may not what you want.
As Christopher and Dor noted, this is almost certainly better done in your code. Still, just for fun, here is how you might do it in MySQL.
SELECT SUBSTRING(`your_column`, LOCATE('>', `your_column`,
LOCATE('<', `your_column`)) + 1)
FROM `your_table`;