Substring in SQL with from a pattern - sql

I am struggling to substring and get the values in SQL.
I am having a JSON String like the following:
DECLARE #string varchar(max)= '[{"CustomFieldId":18,"FieldName":"ABCD","FieldType":"freeText","FieldValue":null,"Details":null,"Value":null,"RelationTable":null,"Isisible":true,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"TESTUSER"},{"CustomFieldId":19,"FieldName":"Workdomain","FieldType":"freeText","FieldValue":null,"Details":null,"Value":null,"RelationTable":null,"IsVisible":true,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"149645"},{"CustomFieldId":20,"FieldName":"TEST1234","FieldType":"freeText","FieldValue":"Sometest","Details":null,"Value":null,"RelationTable":null,"IsVisible":false,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"_listlovFields":[],"org4Values":[],"LoggedInUser":"TESTUSER"}]'
or it can also be like this:
DECLARE #string varchar(max) = '[{"CustomFieldId":20,"FieldName":"TEST1234","FieldType":"freeText","FieldValue":"Sometest","Details":null,"Value":null,"RelationTable":null,"IsVisible":false,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"TESTUSER"}]'
Now from any one of them I need to get the 'FieldValue' of a particular 'CustomFieldId' with a particular 'FieldName' and where the FieldValue starts with a particular string.
Like, I am going to get these:
declare #propName varchar(max) = 'Test1234',
#customFieldId varchar(max) = 20,
#value varchar(max) = 'Some'
So, in this particular case, I need to get the FieldValue of customfield with CustomFieldId:"20", FieldName":"TEST1234" and where FieldValue starts with 'Some'.
The output simply needs be the string 'Sometest' as this is the FieldValue of CustomFieldId:"20"
Any help in this would be highly appreciated.

this is quite easy to solve when you install regex functions on your sql server. I've included the link where you can find them.
https://www.simple-talk.com/sql/t-sql-programming/clr-assembly-regex-functions-for-sql-server-by-example/
declare #CustomFieldId nvarchar(50)= '20'
declare #FieldName nvarchar(50) = 'TEST1234'
declare #FieldValueStartsWith nvarchar(50) = 'Some'
declare #input nvarchar(500)
select #input = '[{"CustomFieldId":20,"FieldName":"TEST1234","FieldType":"freeText","FieldValue":"Sometest","Details":null,"Value":null,"RelationTable":null,"IsVisible":false,"IsAdmin":false,"CreatedDate":null,"ModifiedDate":null,"LoggedInUser":"TESTUSER"}]'
declare #result nvarchar(500)
declare #expression nvarchar(200) = '.*"CustomFieldId":' + #CustomFieldId + ',"FieldName":"' + #FieldName + '".*"FieldValue":("' + #FieldValueStartsWith + '\w+").*'
select #result = dbo.RegExReplaceX(#expression,#input,'$1',dbo.RegExOptionEnumeration(0,0,0,0,1,0,0,0,0)) -- OPTION = FOR CASE SENSITIVE
if #result = #input SELECT NULL ELSE SELECT #RESULT

Related

Extract characters after character '_' in string

I have the following string in sql server where the length is variable
Declare #string Varchar(max) = 'abjrc_chdc_hyku_abv_ytr_DCD_HTR_TBF'
How could I select the characters after the 4th '_' in this string? (expected result: ytr_DCD_HTR_TBF)
Also how to select only the 4th part of the string (result: abv)
Any Ideas?
Thanks
If you know exactly how many characters are in the string at any time, then you can use SUBSTRING, so you can call the first string like this
Declare #string Varchar(max) = 'abjrc_chdc_hyku_abv_ytr_DCD_HTR_TBF';
Declare #last4 Varchar(max) = SELECT SUBSTRING(#string, 21, 35);
Declare #before4 Varchar(max) = SELECT SUBSTRING(#string, 17, 19);
If y ou really need to split the string for each '_' then you can use this as well
hope i helped.
If you will do it for multiple line creating function would be better. I have prepared sample for your two question :
Declare #string Varchar(max) = 'abjrc_chdc_hyku_abv_ytr_DCD_HTR_TBF'
Declare #NewString Varchar(max) = #string
Declare #Find4thPart Varchar(max) =''
DECLARE #Sep VARCHAR(10)='_'
DECLARE #Pos INT=4
WHILE #Pos>0
BEGIN
SET #NewString = SUBSTRING(#NewString, CHARINDEX(#Sep,#NewString)+1,100)
IF #Pos=2
SET #Find4thPart = SUBSTRING(#NewString,1, CHARINDEX(#Sep,#NewString)-1)
SET #Pos=#Pos-1
--SELECT #NewString
END
seLECT #NewString ,#Find4thPart

How to parse json data in SQL Server 2012?

I am using SQL Server 2012.I have been assigned a task where one of my column (JsonText) of table Sample contains json data. I want to pass parse that data and insert into columns of another table (Test). I searched on net 'openjson' is supported in SQL Server 2016. How to do in SQL Server 2012?
Table1 : Sample
Id JsonText Active
JsonText
webaddress?{'data':'{"PId": "XXXX","Status": "YES","Name":"XXX","Address":"XXXX","MobileNumber":"xxx"}'}
I am intrested only 'PID,Address,MobileNumber' columns not all.
Table Test structure like this
Id, PID, Address, MobileNumber
Isaac your code is not working with not quoted values e.g. {"isAuthorized":"false","customerID":null}. I fixed this and your function should look like this.
ALTER FUNCTION [dbo].[JSON_VALUE]
(
#JSON NVARCHAR(3000),
#column NVARCHAR(3000)
)
RETURNS NVARCHAR(3000)
AS
BEGIN
DECLARE #value NVARCHAR(3000);
DECLARE #trimmedJSON NVARCHAR(3000);
DECLARE #start INT;
DECLARE #end INT;
set #start = PATINDEX('%' + #column + '":%',#JSON) + LEN(#column) + 2;
SET #trimmedJSON = SUBSTRING(#JSON, #start, LEN(#JSON));
Set #end = CHARINDEX(',',#trimmedJSON);
SET #value = REPLACE(SUBSTRING(#trimmedJSON, 0, #end),'"','');
RETURN #value
END
I created a function compatible with SQL 2012 to take care of this
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Isaac Adams
-- Create date: 7/12/2018
-- Description: Give the JSON string and the name of the column from which you want the value
-- =============================================
CREATE FUNCTION JSON_VALUE
(
#JSON NVARCHAR(3000),
#column NVARCHAR(3000)
)
RETURNS NVARCHAR(3000)
AS
BEGIN
DECLARE #value NVARCHAR(3000);
DECLARE #trimmedJSON NVARCHAR(3000);
DECLARE #start INT;
DECLARE #length INT;
SET #start = PATINDEX('%' + #column + '":"%',#JSON) + LEN(#column) + 3;
SET #trimmedJSON = SUBSTRING(#JSON, #start, LEN(#JSON));
SET #length = PATINDEX('%", "%', #trimmedJSON);
SET #value = SUBSTRING(#trimmedJSON, 0, #length);
RETURN #value
END
GO
>>> at JSON_VALUE function, at PATINDEX('%", "%', #trimmedJSON);
remove space from '%", "%'
if your JSON value is like
'{"street":"street1","street2":"street232423"}'
You can use JSON_VALUE(ColumnName,'$.Path') for pairs Json in TSQL, for example:
select JSON_VALUE(webaddress,'$.data.PID') as 'PID',
JSON_VALUE(webaddress,'$.data.Status') as 'Status',
JSON_VALUE(webaddress,'$.data.Name') as 'Name'
from test

How to pass parameter value for a string that is inside Variable?

Can some one please help me how can I pass a Parameter value into a string that is inside a Variable
Ex:
DECLARE #STR VARCHAR(MAX) = ''
DECLARE #ID INT
SET #STR = 'SELECT * FROM STUDENT WHERE STUDENT_ID=#ID'
Here I want to pass #ID as a parameter to Variable #STR
Use sp_executesql to value to the parameter this will also avoid sql injection. Try this
DECLARE #STR NVARCHAR(MAX) = ''
DECLARE #ID INT
SET #STR = 'SELECT * FROM STUDENT WHERE STUDENT_ID=#ID'
exec sp_executesql #str,'#ID INT',#ID
Use this:
DECLARE #STR VARCHAR(MAX) = ''
DECLARE #ID INT
SET #STR = 'SELECT * FROM STUDENT WHERE STUDENT_ID=' + CAST(#ID AS VARCHAR(50))
Here's one easy way:
DECLARE #STR VARCHAR(MAX) = ''
DECLARE #ID INT
SET #STR = 'SELECT * FROM STUDENT WHERE STUDENT_ID=#ID'
SET #STR = REPLACE(#STR, '#ID', COALESCE(CAST(#ID AS varchar(31)),''))
And of course there are others. You could have used string concatenation when building #STR, or you could keep it the way it is and use a parameterized call to sp_executesql when you finally want to execute the string, assuming that's what you want to do with it.
You can write a query as:
DECLARE #ID int;
--to use sp_executesql sql statement must be a Unicode variable
DECLARE #STR nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
/* Build the SQL string.
as a best practice you should specify column names instead of writing *
*/
SET #STR =
N'SELECT Col1,Col2 FROM STUDENT WHERE STUDENT_ID=#ID';
SET #ParmDefinition = N'#ID Int';
/* Execute the string with the parameter value. */
SET #ID = 1;
EXECUTE sp_executesql #STR, #ParmDefinition,
#ID = #ID;
For simplicity you can also create a Store Procedure for it:-
Code in SQL
Create Proc [ProcedureName]
#ID As int
As
SELECT * FROM STUDENT WHERE STUDENT_ID=#ID
Calling a Store Procedure
[ProcedureName] 1
--Here replace "1" with your Id
DECLARE #STR VARCHAR(MAX) = ''
DECLARE #ID INT
SET #STR = 'SELECT * FROM STUDENT WHERE STUDENT_ID='+#ID
should do

SQL extracting data from SQL column

I have SQL table JSON data into one of the columns. The column type is varchar max.
I have to extract the data from that column using sql. For example
{"RESPONSE":{"value":"<p>this is a test.....</p>","isAnswered":true}}'
I want to extract: this is a test.....
and get rid of all attributes and Nodes
I am very new to JSON. Fisrt time looking into it and lost
You can try this:
begin transaction
declare #string varchar(max)
declare #result varchar(max)
declare #response varchar(max)
set #string = '{"RESPONSE":{"value":["d"],"isAnswered":true}}'
set #response = SUBSTRING(#string, PATINDEX('%response%',#string), PATINDEX('%":{"value"%',#string) - PATINDEX('%response%',#string))
print #response
-- for html tags
DECLARE #htmlTags TABLE
(
ID INT IDENTITY(1,1),
htmlTag varchar(50)
);
INSERT INTO #htmlTags
VALUES
('<p>'),
('</p>'),
('<h1>'),
('</h1>'),
('"'),
('{'),
('}'),
(':'),
(','),
('value'),
('isAnswered'),
('true'),
('false'),
(' '),
('['),
(']')
;
SET #result = #string
DECLARE #temp varchar(max) = '';
WHILE #result != #temp
BEGIN
SET #temp = #result;
SELECT
#result = Replace(#result, htmlTag, '')
FROM
#htmlTags
;
END;
set #result = REPLACE(#result, #response, '')
print #result
rollback
I'm assuming that the structure of your JSON response is:
{"RESPONSE":{"value":"","isAnswered":true}}
EDIT: I recommend to insert all html tags and names (like ) into the htmlTags table to obtain the result you want since you cannot predict which one of them is going to appear in the json.
UPDATE: use this set #response = SUBSTRING(#string, PATINDEX('%response%',#string), PATINDEX('%":{"value"%',#string) - PATINDEX('%response%',#string)) so you can replace any kind of RESPONSE pattern in your json.
Hope it helps.

SQL substring of URL

I am trying to select a part of a url which is after a wildcard expression and before another expression using SQL Server 2008 R2.
I have a url like:
https%www.msn.com%2ftokenauth%mapserver%ftoken%aogvgkooo%json
or:
https%www.msn.com%2ftokenauth%mapserver%token=aogvgkooo%json.
How do I write a sql query to only show aogvgkooo? The url is stored in column called url.
Here is my select statement:
select REPLACE(REPLACE(url, 'token=', ''),'%json', '')
have you looked at SUBSTRING, CHARINDEX or PATINDEX functions? this site gives a good explanation of them:
http://social.technet.microsoft.com/wiki/contents/articles/17948.t-sql-right-left-substring-and-charindex-functions.aspx
and this one gives an example as well
http://sqlzoo.net/howto/source/u.cgi/tip238311/sqlserver
DECLARE #url varchar(100)
SET #url ='https%www.msn.com%2ftokenauth%mapserver%token=aogvgkooo%json'
SELECT Replace(Replace(Replace(#url,substring(#url,1,Patindex('%token=%',#url)-1),''),'token=',''),'%json','')
sql fiddler
A user-defined function might be a good choice.
create function findToken (
#url nvarchar(max),
#tag nvarchar(100),
#after nvarchar(100)
) returns nvarchar(max) as begin
declare #token nvarchar(max);
declare #start int = charindex(#tag,#url) + len(#tag);
declare #justPast int = charindex(#after,#url,#start);
if #start = len(#tag) or #justPast = 0
return NULL;
return substring(#url,#start,#justPast-#start)
end;
go
declare #url varchar(100);
set #url ='https%www.msn.com%2ftokenauth%mapserver%token=aogvgkooo%json';
select
dbo.findToken(#url,'token=','%json');
DECLARE #url nvarchar(255),
#startPos nvarchar(100),
#endPos nvarchar(100)
SET #url ='https%www.msn.com%2ftokenauth%mapserver%token=aogvgkooo%json'
SET #startPos = 'token%'
SET #endPos = '%json'
SELECT SUBSTRING(#url,CHARINDEX(#startPos,REPLACE (#url,'=','%'),0)+ LEN(#startPos) ,CHARINDEX(#endPos,REPLACE (#url,'=','%'),0)-(CHARINDEX(#startPos,REPLACE (#url,'=','%'),0)+ LEN(#startPos)))
More general approach:
DECLARE #s VARCHAR(100) = 'https%www.msn.com%2ftokenauth%mapserver%ftoken%aogvgkooo%json'
SELECT REVERSE(SUBSTRING(
REVERSE(#s),
CHARINDEX('%', REVERSE(#s)) + 1,
CHARINDEX('%', REVERSE(#s), CHARINDEX('%', REVERSE(#s)) + 1) -
CHARINDEX('%', REVERSE(#s)) - 1))
Reversing string, then take substring from first occurence of % till second occurence, then reversing again.