sql str replace problems - sql

I have been trying to replace a list of about 100 entries of a url in a database and haven't had much luck. This is what I need to do:
Grab current URL: /one/two/three/four/differenteverytime.pdf
and update it in it's current entry to: /two/three/four/differenteverytime.pdf
Every URL starts with that pattern so I am looking to mass update.
I have tried a number of commands with REPLACE and str_REPLACE, but to no avail. Any help is much appreciated, I wasn't able to find a straightforward answer in older entries.

How about something like this
DECLARE #str VARCHAR(MAX) = '/one/two/three/four/differenteverytime.pdf'
SELECT STUFF(#str, 1, LEN(LEFT(#str, CHARINDEX('/', #str, 2)))-1 , '')
using this as part of an UPDATE you would do
UPDATE tbl
SET col = STUFF(col, 1, LEN(LEFT(col, CHARINDEX('/', col, 2)))-1 , '')

Related

I have two strings in my SQL Server database and I want to get specific values from them in a query

The first string is
www.abc.c/item/itemscode/012345678974-Thisisname
I want to get the only portion that is between / and _ i.e only 012345678974
The second is
abc.org.c/items/item_database/number_3_of_10-klsnfdsfjsd.txt
From this string I want to get only 3 from "number_3_of...."
How can I do it. I tried many solution but i could not do it in past more than 48 hours
There are many different ways to achieve this. One way to achieve this is by using Left(), Reverse() and Charindex() function. You need to search for the pattern in your string and base your solution depending on that. Try this:
--First string
DECLARE #string VARCHAR(255)= 'www.abc.c/item/itemscode/012345678974-Thisisname';
SELECT LEFT(REVERSE(LEFT(REVERSE(#string), CHARINDEX('/', REVERSE(#string))-1)), CHARINDEX('-', REVERSE(LEFT(REVERSE(#string), CHARINDEX('/', REVERSE(#string))-1)))-1);
--Second String
DECLARE #string2 VARCHAR(255)= 'abc.org.c/items/item_database/number_3_of_10-klsnfdsfjsd.txt';
SELECT REPLACE(REPLACE(LEFT(REVERSE(LEFT(REVERSE(#string2), CHARINDEX('/', REVERSE(#string2))-1)), CHARINDEX('-', REVERSE(LEFT(REVERSE(#string2), CHARINDEX('/', REVERSE(#string2))-1)))-1), 'NUMBER_', ''), '_OF_10', '');

How to select specific text from the string in efficient way using SQL

Below is my query. It is giving me correct output but I need to run it efficiently as it is used for 500k records.
DECLARE #DESC_MESSAGE VARCHAR(5000)
SET #DESC_MESSAGE = '12345 VENKAT was entered ODC ABCD-3'
SELECT REPLACE(#DESC_MESSAGE,SUBSTRING(#DESC_MESSAGE,1,CHARINDEX('was',#DESC_MESSAGE,3)-1),'')
I just want to retrieve text after 'was' which can change depending on condition.
for ex. text can be like
'112233 XYZ was entered ODC PQRS-3' or
'223344 HARRY was gone out of ODC AMD-3'
Please suggest efficient way to retrieve such text.
I would be inclined to use stuff():
select stuff(col, 1, chardindex('was ', col + 'was ') + 4, '')
The + 'was + in the charindex() function just guarantees no error if 'was ' is not in the text.
half milion rows is not so huge..
what i can see in your question is that there is an architecture issue,
why do you need to split a column to make a query?
why don't you keep the colums splitted in origin ?
eventually you could have another column that contains only the text after the "was"
this could be better even if the rows grow a lot.
select LTRIM(stuff(#DESC_MESSAGE, 1, CHARINDEX(' was', #DESC_MESSAGE + 'was') + 3, ''))

SQL Server query to remove the last word from a string

There's already an answer for this question in SO with a MySQL tag. So I just decided to make your lives easier and put the answer below for SQL Server users. Always happy to see different answers perhaps with a better performance.
Happy coding!
SELECT SUBSTRING(#YourString, 1, LEN(#YourString) - CHARINDEX(' ', REVERSE(#YourString)))
Edit: Make sure #YourString is trimmed first as Alex M has pointed out:
SET #YourString = LTRIM(RTRIM(#YourString))
Just an addition to answers.
The doc for LEN function in MSSQL:
LEN excludes trailing blanks. If that is a problem, consider using the DATALENGTH (Transact-SQL) function which does not trim the string. If processing a unicode string, DATALENGTH will return twice the number of characters.
The problem with the answers here is that trailing spaces are not accounted for.
SELECT SUBSTRING(#YourString, 1, LEN(#YourString) - CHARINDEX(' ', REVERSE(#YourString)))
As an example few inputs for the accepted answer (above for reference), which would have wrong results:
INPUT -> RESULT
'abcd ' -> 'abc' --last symbol removed
'abcd 123 ' -> 'abcd 12' --only removed only last character
To account for the above cases one would need to trim the string (would return the last word out of 2 or more words in the phrase):
SELECT SUBSTRING(RTRIM(#YourString), 1, LEN(#YourString) - CHARINDEX(' ', REVERSE(RTRIM(LTRIM(#YourString)))))
The reverse is trimmed on both sides, that is to account for the leading as well as trailing spaces.
Or alternatively, just trim the input itself.
DECLARE #Sentence VARCHAR(MAX) = 'Hi This is Pavan Kumar'
SELECT SUBSTRING(#Sentence, 1, CHARINDEX(' ', #Sentence) - 1) AS [First Word],
REVERSE(SUBSTRING(REVERSE(#Sentence), 1,
CHARINDEX(' ', REVERSE(#Sentence)) - 1)) AS [Last Word]
DECLARE #String VARCHAR(MAX) = 'One two three four'
SELECT LEFT(#String,LEN(#String)-CHARINDEX(' ', REVERSE(#String),0)+1)
All the answers so far are actually about removing a character, not a word as the OP wanted.
In my case I was building a dynamic SQL statement with UNION'd SELECT statements and wanted to remove the last UNION:
DECLARE #sql NVARCHAR(MAX) = ''
/* populate #sql with something like this:
SELECT 1 FROM dbo.T1 WHERE condition
UNION
SELECT 1 FROM dbo.T2 WHERE condition
UNION
SELECT 1 FROM dbo.T3 WHERE condition
UNION
SELECT 1 FROM dbo.T4 WHERE condition
UNION
*/
-- remove the last UNION
SET #sql = SUBSTRING(#sql, 1, LEN(#sql) - PATINDEX(REVERSE('%UNION%'), REVERSE(#sql)) - LEN('UNION'))
SELECT LEFT(username , LEN(json_path) - CHARINDEX('/', REVERSE(username ))+1)
FROM Login_tbl
UPDATE Login_tbl
SET username = LEFT(username , LEN(json_path) - CHARINDEX('/', REVERSE(username ))+1)
DECLARE #String VARCHAR(MAX) = 'One two three four'
SELECT LEFT(#String,LEN(#String)-CHARINDEX(' ', REVERSE(#String),0)+1)

SQL SERVER 2008 - Returning a portion of text using SUBSTRING AND CHARINDEX. Need to return all text UNTIL a specific char

I have a column called 'response' that contains lots of data about a person.
I'd like to only return the info after a specific string
But, using the method below I sometimes (when people have <100 IQ) get the | that comes directly after the required number..
I'd like any characters after the'PersonIQ=' but only before the pipe.
I'm not sure of the best way to achieve this.
Query speed is a concern and my idea of nested CASE is likely not the best solution.
Any advice appreciated. Thanks
substring(response,(charindex('PersonIQ=',response)+9),3)
This is my suggestion:
declare #s varchar(200) = 'aaa=bbb|cc=d|PersonIQ=99|e=f|1=2'
declare #iq varchar(10) = 'PersonIQ='
declare #pipe varchar(1) = '|'
select substring(#s,
charindex(#iq, #s) + len(#iq),
charindex(#pipe, #s, charindex(#iq, #s)) - (charindex(#iq, #s) + len(#iq))
)
Instead of the 3 in your formula you should calculate the space between #iq and #pipe with this last part of the formula charindex(#pipe, #s, charindex(#iq, #s)) - (charindex(#iq, #s) + len(#iq)), which gets the first #pipe index after #iq, and then substructs the index of the IQ value.
Assuming there's always a pipe, you could do this:
substring(stuff(reponse,1,charindex('PersonIQ=',reponse)-1,''),1,charindex('|',stuff(reponse,1,charindex('PersonIQ=',reponse)-1,''))-1)
Or, you could convert your string to xml and reference PersonIQ directly, e.g.:
--assuming your string looks something like this..
declare #s varchar(max) = 'asdaf=xxx|PersonIQ=100|xxx=yyy'
select convert(xml, '<x ' + replace(replace(#s, '=', '='''), '|', ''' ') + '''/>').value('(/x/#PersonIQ)[1]','int')

Keep end of url in SQL

I have a stored procedure that gives back a string that reads like //path1/path2/item.itm, //path1/path3/item.itm or //path4/path5/item.itm what I would like to do is have it just return something like /path2/item.itm I know that there is a replace in sql along the lines of REPLACE(String, ‘//path1’, ‘’) but this wont work since the string is not consistent in all entries. I cant do this in the code because I may need to put the values back in.
If I were to do this in code (which I cant do) it would be something along the lines of
string = string.Remove(string.LastIndexOf('/'),
string.Length - string.LastIndexOf('/'));
but I have no idea how to do this in SQL or any idea if it can be done.
You can use this:
declare #str varchar(100) = '//path1/path2/item.itm'
select SUBSTRING(#str, PATINDEX('%[^/]/%', #str) + 1, LEN(#str) - PATINDEX('%[^/]/%', #str))
or, if you know max length of your strings (I assume), says max = 8000, you can use this:
select SUBSTRING(#str, PATINDEX('%[^/]/%', #str) + 1, 8000)
I'm not sure if this would be faster than PATINDEX() but you could reverse the string take up to the / then reverse it again something like this:
SELECT REVERSE(LEFT(REVERSE(path),CHARINDEX('/',REVERSE(path))))
nb, I didn't test so I might have a typo.