Keep end of url in SQL - 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.

Related

SQL Substring function usage

This the column Description
Entity=10||WorkdayReferenceID=9000100332||HCMCostCenterMgr=nicoleb#broadinstitute.org||FRP=||
I want to retrieve the emailid only in the above scenario the desired output would be
nicoleb#broadinstitute.org
I tried using this:
select RTRIM(NVL(SUBSTR(TL.DESCRIPTION,(INSTR(TL.DESCRIPTION, '=',1,3)+1),
(LENGTH(TL.DESCRIPTION)-1)),'TL.DESCRIPTION'), '|') AS CCM
But after that new value of FRP was added so it got wrong .
Assuming (and it is a big assumption) that there is only ever one # in the data, the approach would be find the #, and then you want the text that is after the preceding = and before the next |. I do not know if the email address is always after HCMCostCenterMgr= so I won't assume that (but if that is the case the solution is easier).
It looks like you might be using Oracle (I see a NVL function), but I did this as SQL Server (it is more familiar off the top of my head). Here is a small script that will return just the email address you want - you can easily change these functions to Oracle if you need a version for Oracle.
DECLARE #data VARCHAR(200);
SELECT #data = 'Entity=10||WorkdayReferenceID=9000100332||HCMCostCenterMgr=nicoleb#broadinstitute.org||FRP=||';
SELECT REVERSE(SUBSTRING(REVERSE(SUBSTRING(#data, 1, CHARINDEX('|', #data, CHARINDEX('#', #data)) - 1)), 1, CHARINDEX('=', REVERSE(SUBSTRING(#data, 1, CHARINDEX('|', #data, CHARINDEX('#', #data)) - 1)))-1));
It is ugly, but SQL often gets a bit convoluted. I had to reverse the string to find things before the '#' and then reverse it at the end to get the value in the correct direction.

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', '');

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')

Simple Explanation for PATINDEX

I have have been reading up on PATINDEX attempting to understand what and why. I understand the when using the wildcards it will return an INT as to where that character(s) appears/starts. So:
SELECT PATINDEX('%b%', '123b') -- returns 4
However I am looking to see if someone can explain the reason as to why you would use this in a simple(ish) way. I have read some other forums but it just is not sinking in to be honest.
Are you asking for realistic use-cases? I can think of two, real-life use-cases that I've had at work where PATINDEX() was my best option.
I had to import a text-file and parse it for INSERT INTO later on. But these files sometimes had numbers in this format: 00000-59. If you try CAST('00000-59' AS INT) you'll get an error. So I needed code that would parse 00000-59 to -59 but also 00000159 to 159 etc. The - could be anywhere, or it could simply not be there at all. This is what I did:
DECLARE #my_var VARCHAR(255) = '00000-59', #my_int INT
SET #my_var = STUFF(#my_var, 1, PATINDEX('%[^0]%', #my_var)-1, '')
SET #my_int = CAST(#my_var AS INT)
[^0] in this case means "any character that isn't a 0". So PATINDEX() tells me when the 0's end, regardless of whether that's because of a - or a number.
The second use-case I've had was checking whether an IBAN number was correct. In order to do that, any letters in the IBAN need to be changed to a corresponding number (A=10, B=11, etc...). I did something like this (incomplete but you get the idea):
SET #i = PATINDEX('%[^0-9]%', #IBAN)
WHILE #i <> 0 BEGIN
SET #num = UNICODE(SUBSTRING(#IBAN, #i, 1))-55
SET #IBAN = STUFF(#IBAN, #i, 1, CAST(#num AS VARCHAR(2))
SET #i = PATINDEX('%[^0-9]%', #IBAN)
END
So again, I'm not concerned with finding exactly the letter A or B etc. I'm just finding anything that isn't a number and converting it.
PATINDEX is roughly equivalent to CHARINDEX except that it returns the position of a pattern instead of single character. Examples:
Check if a string contains at least one digit:
SELECT PATINDEX('%[0-9]%', 'Hello') -- 0
SELECT PATINDEX('%[0-9]%', 'H3110') -- 2
Extract numeric portion from a string:
SELECT SUBSTRING('12345', PATINDEX('%[0-9]%', '12345'), 100) -- 12345
SELECT SUBSTRING('x2345', PATINDEX('%[0-9]%', 'x2345'), 100) -- 2345
SELECT SUBSTRING('xx345', PATINDEX('%[0-9]%', 'xx345'), 100) -- 345
Quoted from PATINDEX (Transact-SQL)
The following example uses % and _ wildcards to find the position at
which the pattern 'en', followed by any one character and 'ure' starts
in the specified string (index starts at 1):
SELECT PATINDEX('%en_ure%', 'please ensure the door is locked');
Here is the result set.
8
You'd use the PATINDEX function when you want to know at which character position a pattern begins in an expression of a valid text or character data type.

sql str replace problems

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 , '')