August 23, 2019 at 5:57 pm
Hi,
I have a string nvarchar(255) and I am try to convert the ASCII codes in it and also extract part of the string.
Here is an example of a value: urn:ADL:CC_LB_SF_EN_D_C_%5BLB_LS_TCD%5D_%5BLB_LS_CotCF%5D_28_1
This is what I would like to convert it to: urn:ADL:CC_LB_SF_EN_D_C_[LB_LS_TCD]_[LB_LS_CotCF]_28_1
Then I would like to select what is between urn:ADL: and the last _
I tried SELECT SUBSTRING(interaction_id, CHARINDEX('ADL:', interaction_id), CHARINDEX('_%5',interaction_id) - CHARINDEX('ADL:', interaction_id) + Len('_%5')) AS substring
to get me started with the part of the string I need, but that SELECT statement gets me: ADL:CC_CLB_SF_EN_D_C_%5
Clearly I am not very good at this string manipulation stuff, but I would like to learn.
What SELECT statement gets me to CC_LB_SF_EN_D_C_[LB_LS_TCD]_[LB_LS_CotCF]_28
Help!
August 23, 2019 at 6:07 pm
;WITH CTE AS
(
SELECT 'urn:ADL:CC_LB_SF_EN_D_C_%5BLB_LS_TCD%5D_%5BLB_LS_CotCF%5D_28_1' Original
),
CTE1 AS
(
SELECT *,
REPLACE(REPLACE(CTE.Original,'%5B','['),'%5D',']') SquareBrackets
FROM CTE
),
CTE2 AS
(
SELECT *,
SUBSTRING(CTE1.SquareBrackets,CHARINDEX('ADL:',CTE1.SquareBrackets,1)+LEN('ADL:'),10000) RemovedADL
FROM CTE1
),
CTE3 AS
(
SELECT *,
SUBSTRING(CTE2.RemovedADL,1,LEN(CTE2.RemovedADL)-CHARINDEX('_',REVERSE(CTE2.RemovedADL))) Final
FROM CTE2
)
SELECT *
FROM CTE3
You can combine it all into one expression but it wouldn't be very readable
August 23, 2019 at 6:29 pm
That returns urn:ADL:CC_LB_SF_EN_D_C_[LB_LS_TCD]_[LB_LS_CotCF]_28_1 and I need ADL:CC_LB_SF_EN_D_C_[LB_LS_TCD]_[LB_LS_CotCF]_28 returned. Everything between the urn: and the last _
Also, I should have been clearer. I have hundreds, if not a thousand of these to convert, so I need a select statement that replaces every occurance of %5B with [ and %5D with ]
For each string, the logic will always be everything between the urn: and the last _
Thanks and sorry for not being clearer.
August 23, 2019 at 6:32 pm
Please disregard my post #3674055. It was a reply to a post no longer there 🙁
August 23, 2019 at 6:39 pm
I was hoping to have it as 1 select statement as I have to join it to other data. I do appreciate what you showed me however, as it breaks it down step by step. Now I need to figure out how to combine a REPLACE and 2 SUBSTRINGS onto 1 line!
August 23, 2019 at 7:52 pm
I was hoping to have it as 1 select statement as I have to join it to other data. I do appreciate what you showed me however, as it breaks it down step by step. Now I need to figure out how to combine a REPLACE and 2 SUBSTRINGS onto 1 line!
I think with something that complicated you'd be better off putting it in several CROSS APPLY operators. You can then join on results of the final CROSS APPLY
;WITH CTE AS (SELECT 'urn:ADL:CC_LB_SF_EN_D_C_%5BLB_LS_TCD%5D_%5BLB_LS_CotCF%5D_28_1' Original)
SELECT W.Original, Z.Final
FROM CTE W
CROSS APPLY(VALUES (REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'))) X(SquareBrackets)
CROSS APPLY(VALUES (SUBSTRING(X.SquareBrackets,CHARINDEX('ADL:',X.SquareBrackets,1)+LEN('ADL:'),10000))) Y(RemovedADL)
CROSS APPLY(VALUES (SUBSTRING(Y.RemovedADL,1,LEN(Y.RemovedADL)-CHARINDEX('_',REVERSE(Y.RemovedADL))))) Z(Final)
August 23, 2019 at 8:13 pm
i think this will fix just two items though; won't he have continued issues when he discovers %20 or other url encoded values?
i would think we need to consider all the other outlier values that will get encoded as well.
this has some scalar examples that probably point to teh right direction:
https://stackoverflow.com/questions/3833229/sql-server-url-decoding
and here is a reference to the url encoded characters in general, just to visualize.
https://www.degraeve.com/reference/urlencoding.php
Lowell
August 23, 2019 at 8:54 pm
Thanks to Jonathan AC Roberts and Lowell. I'm going to try and see if I can get this on one line or join the CTE to my existing data. For Lowell, the format of the data is very specific and while I am sure other URL encoded values may sneak into the database, I have verified %5B and %5D are the only ones I have to deal with out of ~10,000 rows.
August 23, 2019 at 11:02 pm
Just paste in your original query and I'll show you how it can be done.
August 24, 2019 at 11:48 pm
if you want it in one line then here it is, but I wouldn't recommend it
;WITH CTE AS (SELECT 'urn:ADL:CC_LB_SF_EN_D_C_%5BLB_LS_TCD%5D_%5BLB_LS_CotCF%5D_28_1' Original)
SELECT W.Original, Z.Final
FROM CTE W
CROSS APPLY(VALUES (SUBSTRING(SUBSTRING(REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'),CHARINDEX('ADL:',REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'),1)+4,10000),1,LEN(SUBSTRING(REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'),CHARINDEX('ADL:',REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'),1)+4,10000))-CHARINDEX('_',REVERSE(SUBSTRING(REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'),CHARINDEX('ADL:',REPLACE(REPLACE(W.Original,'%5B','['),'%5D',']'),1)+4,10000)))))) Z(Final)
August 25, 2019 at 2:39 am
Just my take on this... single and fairly short formula that does the replacements only once. This, of course, assumes that you'll always be working values where you want to throw away the first 8 characters, which is 'urn:ADL:' in your example.
DECLARE @SomeString NVARCHAR(255) = N'urn:ADL:CC_LB_SF_EN_D_C_%5BLB_LS_TCD%5D_%5BLB_LS_CotCF%5D_28_1';
;
SELECT REPLACE(REPLACE(SUBSTRING(@SomeString,9,LEN(@SomeString)-CHARINDEX(N'_',REVERSE(@SomeString))-8),N'%5B',N'['),N'%5D',N']')
;
--Jeff Moden
Change is inevitable... Change for the better is not.
August 27, 2019 at 3:52 pm
Thanks Jeff. This appears to be exactly what I am looking for. How would I replace the string with a field name called int_ID now? I don't know what to do with the N'. I'm not a programmer or dba. I am a business analyst and I use SQL to help me analyze data.
I tried this, but it returns empty cells. I know I need to do something with the N', but I don't know what.
SELECT REPLACE(REPLACE(SUBSTRING(int_id,9,LEN(int_id)-CHARINDEX(N'_',REVERSE(int_id))-8),N'%5B',N'['),N'%5D',N']') FROM AI_int
Sorry for the delay in responding. I was away for the weekend.
August 27, 2019 at 5:35 pm
Actually, the query was fine. It was the data I joined it to was the problem. After correcting my error and using the specific data set I wanted to see, it worked perfectly.
Thanks to Jeff for teaching me something new and also to Jonathan. Your queries worked as well and taught me something as well. Hopefully I can reuse these once I study them some more.
August 27, 2019 at 6:30 pm
Thanks Jeff. This appears to be exactly what I am looking for. How would I replace the string with a field name called int_ID now? I don't know what to do with the N'. I'm not a programmer or dba. I am a business analyst and I use SQL to help me analyze data.
I tried this, but it returns empty cells. I know I need to do something with the N', but I don't know what.
SELECT REPLACE(REPLACE(SUBSTRING(int_id,9,LEN(int_id)-CHARINDEX(N'_',REVERSE(int_id))-8),N'%5B',N'['),N'%5D',N']') FROM AI_int
Sorry for the delay in responding. I was away for the weekend.
I assume that INT_ID is an integer. That's a totally different requirement and won't contain a string to be parsed.
Edit... I forgot to refresh the screen and missed your previous post above. Glad you figured it out and thank you for the feedback.
--Jeff Moden
Change is inevitable... Change for the better is not.
August 27, 2019 at 6:34 pm
Thanks Jeff. It is not an integer field - int was short for interactions.
Viewing 15 posts - 1 through 14 (of 14 total)
You must be logged in to reply to this topic. Login to reply