sqlsql-server

Find all occurrences of Substring and replace it with a special characters


I have a string like this:

DECLARE @TEXT nvarchar(max) = 'Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER_400_40S+1x2JHT-4KB_400_40S_3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F'

I want to identify the string between LT_ and MT_ which is

1x2KJU-4ER_400_40S+1x2JHT-4KB_400_40S_3

and replace the _ with @@ which would produce this result:

1x2KJU-4ER@@400@@40S+1x2JHT-4KB@@400@@40S@@3

I want to replace that string with original string @TEXT which looks like

Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER@@400@@40S+1x2JHT-4KB@@400@@40S@@3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F

And now I want to identify the string between MT_ and _UAN which would be

1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF

and replace the _ with @@ which would look like this:

1x4GIE-20KC@@400@@40P@@OLM+2x4MNB-20KC@@400@@40P@@SDF

and replace the above string with original string @TEXT to look lie this:

Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER@@400@@40S+1x2JHT-4KB@@400@@40S@@3MT_1x4GIE-20KC@@400@@40P@@OLM+2x4MNB-20KC@@400@@40P@@SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F

NOTE: there is no guarantee that string will always contains both LT_ and MT_ in @TEXT, and it will contain either LT_ or MT_ or it can contains both.

Possible values of @TEXT

Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER_400_40S+1x2JHT-4KB_400_40S_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F

and

Note Book_AK47_SINGLE AP/PS_20/40/09/209_3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F

My input string =

Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER_400_40S+1x2JHT-4KB_400_40S_3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F

My desired output string

Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER@@400@@40S+1x2JHT-4KB@@400@@40S@@3MT_1x4GIE-20KC@@400@@40P@@OLM+2x4MNB-20KC@@400@@40P@@SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F

I have tried like this

Declare @TEXT nvarchar(max) = 'Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER_400_40S+1x2JHT-4KB_400_40S_3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F'

Declare @finalResult nvarchar(max) = @TEXT;
Declare @first nvarchar(max) 
SET @first = (SUBSTRING(@TEXT, CHARINDEX('LT_',@TEXT)+3, CHARINDEX('MT_',@TEXT) - (CHARINDEX('LT_',@TEXT)+3))   )

Select @first

But got this error:

Invalid length parameter passed to the LEFT or SUBSTRING function.


Solution

  • I made a VERY laborus sql query, just to show the steps needed. This can OBVIOUSLY be improved significantly. It is just if you got stuck on any of the steps needed.

    with data (val) as ( select 'Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER_400_40S+1x2JHT-4KB_400_40S_3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P_SDF_UAN_-_Customyats_JSHEYH-SH HGSRWT_DVD_CHOT DR6-4P-4W+CB6-2F-2F')
    ,startFinishVal as (select CHARINDEX('LT_',val)+3 start,  CHARINDEX('MT_',val) fin from data)
    ,startFinishRep as (select 0 s1, CHARINDEX('LT_',val)+3 f1,  CHARINDEX('MT_',val) s2,len(val) f2 from data)
    ,starttext (val) as (select substring((select val from data),s1,f1) from startFinishRep)
    ,endtext (val) as (select substring((select val from data),s2,f1) from startFinishRep)  
    ,Oldval (val) as (select SUBSTRING((select val from data),start,fin-start) from StartFinishVal)
    ,newval (val) as (select replace(val,'_','@@') from Oldval)
    select (select val from starttext) + (select val from newval)+ (select val from endtext)
    

    This results in :

    Note Book_AK47_SINGLE AP/PS_20/40/09/209_6LT_1x2KJU-4ER@@400@@40S+1x2JHT-4KB@@400@@40S@@3MT_1x4GIE-20KC_400_40P_OLM+2x4MNB-20KC_400_40P