SQL substring of URL - sql

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.

Related

How to replace string in SQL from index to index

Hi guys can someone help me to write this?
DECLARE #STR VARCHAR(55) = 'Name';
SELECT // SOME LOGIC
RESULT => 'NXXE'
I would like this logic to be generalized to replace every string except the first and last character.
if dynamic data masking is not an answer you can use query below :
DECLARE #str VARCHAR(100) = 'yourstring'
SELECT UPPER(LEFT(#str,1) + REPLICATE('x',LEN(#str) -2)+ RIGHT(#str,1))
This is what you want
DECLARE #STR VARCHAR(55) = 'Name';
declare #i int
Set #i = 0
while #i <= len(#STR )
begin
select #i = #i + 1
if(#i>1 AND #i<len(#STR ))
select #STR = STUFF(#STR , #i, 1, 'X')
END
SELECT #STR

Substring in SQL with from a pattern

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

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

Using a comma-separated parameter in an IN clause

I have 'param1, param2, parma3' coming from SSRS to a stored procedure as a varchar parameter: I need to use it in a query's IN clause but then need to change its format like this first:
select *
from table1
where col1 in('param1', 'param2', 'param3')
What is the best way to reformat the parameter without creating functions and parameter tables?
Try this one, Just need to add commas at the beginning and at the end of #params string.
Declare #params varchar(100) Set #params = ',param1,param2,param3,'
Select * from t
where CHARINDEX(','+cast(col1 as varchar(8000))+',', #params) > 0
SQL FIDDLE
you can use split function and use it as in following way
here my split fnSplitString return splitdata
select * from tb1 where id in(select splitdata from dbo.fnSplitString((select col1 from tb12 where id=3),','))
create FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output(splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
END
If you are using SQL 2016 and above string_split you can use.
-- #param is where you keep your comma separated values example:
declare #param = 'param1,param2,param3'
select * from table1 where col1 in (select TRIM(value) from string_split(#param,',')
More information about string_split check offical documemt
Furthermore, TRIM() is used to trim values from white spaces.
We can use STRING_SPLIT() in SQL SERVER
DECLARE #params varchar(max)= 'param1,param2,param3'
SELECT *
FROM table1
WHERE col1 IN (SELECT value FROM STRING_SPLIT( #params , ','))
"Best way" is arguable, but one classic approach that remains without "creating functions and table parameters" is to simply employ dynamic SQL in the stored procedure:
-- FORNOW: local to act as the SP param and arg
declare #values varchar(100) = 'param1, param2, param3'
-- Add opening and closing single quotes, then quotes around each
-- comma-separated list item.
select #values = '''' + REPLACE(#values, ', ', ''', ''') + ''''
-- FORNOW: for clarity/debugging
print #values
--'param1', 'param2', 'param3'
-- Run the desired query as dynamic SQL.
DECLARE #sql as nvarchar(250);
SET #sql = 'select * from table1 where col1 in (' + #values + ')';
EXEC sp_executesql #sql;
This assumes a couple things, though:
That commas in the list of values are followed by a space. Variations on this solution can address deviations in this respect of course, but it is important to be aware of this assumption.
That the comma-separated values do not themselves have commas in them – unlikely but worth mentioning since whether values will satisfy this constraint sometimes goes unconsidered.
Load the Params into a string and execute as an sql :
declare #param varchar(1000) = 'param1, param2, parma3'
declare #sql varchar(4000)
select #sql =
'select *
from table1
where col1 in(''' + replace(#param,',',''',''') + ''')'
-- print #sql -- to see what you're going to execute
exec sp_executesql #sql
DECLARE #params varchar(max) = '1,2,3,4'
SELECT * FROM table2 WHERE colId IN (SELECT value FROM SPLIT(#params,','))
Base on id we can find.

How to use IN Operator in SQL Server

How to use IN Operator in SQL Server
Here Is the table Structure
Create Table Sample(Id INT,Name Varchar(50))
While I am the Query like this I can get the Value
Select * FROM Sample WHERE Id IN ('74','77','79','80')
While I am executing the above Query I can't able to get the Records Related to that table getting error executing this error.
DECLARE #s VARCHAR(MAX)
SET #s='74','77','79','80'
Select * FROM Sample WHERE Id IN (#s)
You are using wrong way
use the following way
DECLARE #s VARCHAR(MAX)
DECLARE #d VARCHAR(MAX)
SET #s='74 , 77 , 79 , 80'
set #d = 'select * from arinvoice where arinvoiceid in('+#s+')'
exec (#d)
here IN operator use integers collection not string collection..
you should use a function which gives back a result set ( takes a csv format and returns a table)
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Splitt] (#String NVARCHAR(4000),
#Delimiter CHAR(1))
RETURNS #Results TABLE (
Items NVARCHAR(4000))
AS
BEGIN
DECLARE #Index INT
DECLARE #Slice NVARCHAR(4000)
SELECT #Index = 1
IF #String IS NULL
RETURN
WHILE #Index != 0
BEGIN
SELECT #Index = Charindex(#Delimiter, #String)
IF #Index <> 0
SELECT #Slice = LEFT(#String, #Index - 1)
ELSE
SELECT #Slice = #String
IF ( NOT EXISTS (SELECT *
FROM #Results
WHERE items = #Slice) )
INSERT INTO #Results
(Items)
VALUES (#Slice)
SELECT #String = RIGHT(#String, Len(#String) - #Index)
IF Len(#String) = 0
BREAK
END
RETURN
END
and now you can write :
DECLARE #s VARCHAR(MAX)
SET #s='74,77,79,80'
Select * FROM Sample WHERE Id IN (select items from dbo.Splitt(#s,','))
If you are using ADO.NET, you can avoid the magic string, just use SqlDataRecord.
Or if you are using SQL Server 2008, you can also avoid the magic string by using Table-Valued Parameter
Source: http://www.sommarskog.se/arrays-in-sql-2008.html