SQL Trim on a file name - sql

I am trying to trim a long file name and just want to get the last characters of that file name which is after the last forward slash (\) and I also want to eliminate the .xlsx at the end of the file name as well.
Original:
sasa\sasas\sasas\1234_IASS.xlsx
Expected Output:
1234_IASS

Your comments state that both your file path and file extension are constant. If the number of characters in your file is also constant the simplest solution is to use SUBSTRING.
SELECT SUBSTRING(YourColumn, 18, 9)
FROM YourTable
If the number of characters is changing, a more robust solution is to use RIGHT to extract the file name and REPLACE to remove the file extension.
SELECT REPLACE(RIGHT(YourColumn, LEN(YourColumn) - 17), '.xlsx', '')
FROM YourTable
If you need a more dynamic solution, you can first extract the filename as shown.
SELECT RIGHT(YourColumn, CHARINDEX('\', REVERSE(YourColumn)) - 1)
FROM YourTable
You can then combine this with REPLACE as before to remove the extension.
SELECT REPLACE(RIGHT(YourColumn, CHARINDEX('\', REVERSE(YourColumn)) - 1), '.xlsx', '')
FROM YourTable

You can try this it will work as said in the comment the file extension are fixed.
SELECT
Replace(
RIGHT('\' + RTRIM('sasa\sasas\sasas\1234_IASS.xlsx'), CHARINDEX('\', REVERSE('\' + RTRIM('sasa\sasas\sasas\1234_IASS.xlsx'))) - 1)
,'.xlsx', '')
as FileName
You can find the live example here.

You say your directory is the same and the extension is always the same? Replace [path] with your table column name:
select replace(replace([path],'sasa\sasas\sasas\',''),'.xlsx','')

declare #x varchar(100) = 'sasa\sasas\sasas\1234_IASS.xlsx'
declare #filename varchar(max) = reverse(substring(reverse(#x), 1, charindex('\', reverse(#x))-1 ))
select substring(#filename, 1, charindex('.', #filename)-1)

Your post's title is misleading, TRIM is performed in sql-server to remove whitespace either by RTRIM or LTRIM or a combination of the two, what you are trying to do is get a substring out of your example string, I am providing a solution which uses a combination of REVERSE, SUBSTRING and CHARINDEX, this answer is good for if you ever need to do this for different file extensions:
DECLARE #test varchar(255) = 'sasa\sasas\sasas\1234_IASS.xlsx';
DECLARE #lastOccurance INT = CHARINDEX('\', REVERSE(#test)); --Last occurence of the slash character to denote the end of the directory name or what not
DECLARE #lastPeriod INT = CHARINDEX('.', REVERSE(#test)); --This is the last occurence of the period, denoting the file extension
SET #lastOccurance = LEN(#test) + 1 - #lastOccurance;
SET #lastPeriod = LEN(#test) + 1 - #lastPeriod;
SELECT SUBSTRING(#test, #lastOccurance + 1, #lastPeriod - (#lastOccurance + 1));

If you want to remove extensions from filename then you can try this:
UPDATE TableName
SET FileName = REVERSE(SUBSTRING(REVERSE(FileName),
CHARINDEX('.', REVERSE(FileName)) + 1, 999))

Related

SQL Substring code to deal with extra characters

I have a string in the format 'Filename_30062021_095700.txt' and I wrote some SQL to get the date bit (in the format DDMMYYYY after the first underscore) then convert to an INT:
declare #filename varchar(50), #filename2 varchar(50)
Set #filename = 'Filename_240621_122110.txt'
Set #filename2 = 'Filename_240621_122110_1.txt'
Select CAST(SUBSTRING(#filename, CHARINDEX('_', #filename) + 1, CHARINDEX('.', #filename) - CHARINDEX('_', #filename) - 1) AS Int) As IntDateFilename1
The problem I have is where the filename randomly has an _1 character at the end before the file extension.
I can't see what to do to my query that would cope with the extra '_1'. I've written something to check the number of _ underscore characters and if there are three then I could do something differently, I just can't see what to do for the best.
I thought of more or less the same query, except for a Left(#filename, 15) + '.txt' instead of #filename but is there a better solution in case the DD or MM ever appear as one digit?
I would use the 2 surrounding underscores as the markers here:
SELECT
SUBSTRING(filename, CHARINDEX('_', filename) + 1,
CHARINDEX('_', filename, CHARINDEX('_', filename) + 1) -
CHARINDEX('_', filename) - 1)
FROM yourTable;
Demo
A little trick you can do to deal with your _1 issue in particular is to work with the string reversed, then charindex gives you the correct character postitions and copes equally well with _1234 etc
Set #filename = 'Filename_240621_122110_1234.txt'
select Reverse(Stuff(Reverse(#filename),(1+CharIndex('.',Reverse(#filename))),( CharIndex('_',Reverse(#filename))-CharIndex('.',Reverse(#filename)) ),''))
I would just look for '_' followed by six digits. Then remove the initial part of the string and take 6 digits:
SELECT LEFT(STUFF(filename, 1, PATINDEX('%_[0-9][0-9][0-9][0-9][0-9][0-9]%', filename), ''), 6)
FROM t ;
Or if you prefer using SUBSTRING():
SUBSTRING(filename, PATINDEX('%_[0-9][0-9][0-9][0-9][0-9][0-9]%', filename) + 1, 6)
Here is a db<>fiddle.

Need output of substring sql without using reverse

I have a SQL query which is returning output; I need to get substring with last occurrence, I am confused and not able to find out how to do that:
SELECT
spsetuppath,
SUBSTRING(spsetuppath, 0, (LEN(spsetuppath) - CHARINDEX('\', RTRIM(LTRIM(REVERSE(spsetuppath))))) + 1)
FROM
UMRdb..sql_spversion
WHERE
bitversion = '64'
AND productversion = ' 10.50.2500.0'
Output of this command is as follows
For the last column, I need the path before exe and I need only exe file name - how to do that?
So output I am expecting should look like this
SQLServer2008R2SP1-KB2528583-x64-ENU.exe
select right(spsetuppath, charindex('\', reverse(spsetuppath) + '\') - 1) from UMRdb..sql_spversion where bitversion='64' and
productversion=' 10.50.2500.0 '
this worked awesome.
This should help you:
SELECT
spsetuppath,
SUBSTRING(spsetuppath, CHARINDEX('\', RTRIM(LTRIM(REVERSE(spsetuppath)))) - 1, 150)
FROM
UMRdb..sql_spversion
WHERE
bitversion = '64'
AND productversion = ' 10.50.2500.0'
Example:
DECLARE #string varchar(256) = '\\blablabla\dbms\MSSQL\SQL SERVER 2008\SQLServer2008R2SP1-KB2528583-x64-ENU.exe'
SELECT SUBSTRING(#string, CHARINDEX('\', RTRIM(LTRIM(REVERSE(#string)))) - 1, 150)
EDIT: If you want to avoid SUBSTRING function use this:
DECLARE #string varchar(256) = '\\blablabla\dbms\MSSQL\SQL SERVER 2008\SQLServer2008R2SP1-KB2528583-x64-ENU.exe'
SELECT REVERSE(LEFT(REVERSE(#string),CHARINDEX('\', RTRIM(LTRIM(REVERSE(#string)))) - 1))

stripping just the filename from a string in sql by looking at the '/' dash character

I would like to know how to accomplish getting just the file name from the below
C:\Users\avs\Desktop\Testing\Text Files\TargetFolder\PN005337.RCS
the PN005337.RCS file name can vary in name and length. However the only definitive way of capturing it would be looking at the last '\' and then bringing back any thing after the very last '\'.
Anyway to do that in sql. This is a column in sql server, but the report owner just wants to see the name.
I am doing this in SSIS so either solution would be great in an expression or in SQL.
Thank you
You could determine the index of the last slash by first REVERSE the path and then find the slash by means of CHARINDEX.
Finally you extract the filename applying to the original path the function RIGHT using the found index.
The expression would be RIGHT(path, CHARINDEX('/', REVERSE(path)) - 1)
A case for CROSS APPLY to make intermediate computations
declare #t table (full_path varchar(max));
insert #t values
('C:\Users\avs\Desktop\Testing\Text Files\TargetFolder\PN005337.RCS'),
('C:PN005337.RCS'),
('PN005337.RCS');
SELECT full_path,
CASE WHEN pback>=0 THEN RIGHT(full_path, pback)
WHEN pcol>=0 THEN RIGHT(full_path, pcol)
ELSE full_path
END as fname
FROM #t
CROSS APPLY (
SELECT pback= CHARINDEX('\', REVERSE(full_path)) -1, pCol = CHARINDEX(':', REVERSE(full_path)) -1
) pp

SQL: how to select a substring between special characters

My string looks something like this:
\\\abcde\fghijl\akjfljadf\\
\\xyz\123
I want to select everything between the 1st set and next set of slashes
Desired result:
abcde
xyz
EDITED: To clarify, the special character is always slashes - but the leading characters are not constant, sometimes there are 3 slashes and other times there are only 2 slashes, followed by texts, and then followed by 1 or more slashes, some more texts, 1 or more slash, so on and so forth. I'm not using any adapter at all, just looking for a way to select this substring in my SQL query
Please advise.
Thanks in advance.
You could do a cross join to find the second position of the backslash. And then, use substring function to get the string between 2nd and 3rd backslash of the text like this:
SELECT substring(string, 3, (P2.Pos - 2)) AS new_string
FROM strings
CROSS APPLY (
SELECT (charindex('\', replace(string, '\\', '\')))
) AS P1(Pos)
CROSS APPLY (
SELECT (charindex('\', replace(string, '\\', '\'), P1.Pos + 1))
) AS P2(Pos)
SQL Fiddle Demo
UPDATE
In case, when you have unknown number of backslashes in your string, you could just do something like this:
DECLARE #string VARCHAR(255) = '\\\abcde\fghijl\akjfljadf\\'
SELECT left(ltrim(replace(#string, '\', ' ')),
charindex(' ',ltrim(replace(#string, '\', ' ')))-1) AS new_string
SQL Fiddle Demo2
Use substring, like this (only works for the specified pattern of two slashes, characters, then another slash):
declare #str varchar(100) = '\\abcde\cc\xxx'
select substring(#str, 3, charindex('\', #str, 3) - 3)
Replace #str with the column you actually want to search, of course.
The charindex returns the location of the first slash, starting from the 3rd character (i.e. skipping the first two slashes). Then the substring returns the part of your string starting from the 3rd character (again, skipping the first two slashes), and continuing until just before the next slash, as determined by charindex.
Edit: To make this work with different numbers of slashes at the beginning, use patindex with regex to find the first alphanumeric character, instead of hardcoding that it should be the third character. Example:
declare #str varchar(100) = '\\\1Abcde\cc\xxx'
select substring(#str, patindex('%[a-zA-Z0-9]%', #str), charindex('\', #str, patindex('%[a-zA-Z0-9]%', #str)) - patindex('%[a-zA-Z0-9]%', #str))
APH's solution works better if your string always follows the pattern as described. However this will get the text despite the pattern.
declare #str varchar(100) = '\\abcde\fghijl\akjfljadf\\'
declare #srch char(1) = '\'
select
SUBSTRING(#str,
(CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,1)+1))+1),
CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,1)+1))+1))
- (CHARINDEX(#srch,#str,(CHARINDEX(#srch,#str,1)+1))+1)
)
Sorry for the formatting.
Edited to correct user paste error. :)

SQL substring from a string

I have a table XYZ with column FileName which has values as follows:
CCA_Type-PROPOSAL_Id-45845_Test1.txt
CPA_Type-PROPOSAL_Id-490845_Test2.txt
I want to update this column so that it contains only the filename and remove other characters preceeding:
Test1.txt
Test2.txt
Hence I wrote the following:
Update XYZ
set FileName = (select RIGHT(FileName,CHARINDEX('_',REVERSE(FileName),0)-1))
But if a FileName has a value like:
CCA_Type-PROPOSAL_Id-45845_Test_RR1.txt
My script returns RR1.txt instead of Test_RR1.txt! It finds the last underscore and returns substring from there. How can I change it so that I get the 3rd underscore and return a substring following it!
charindex optionally takes a start location. You could chain several together:
select right(FileName, len(FileName) -
charindex('_', FileName,
charindex('_', FileName,
charindex('_', FileName)
+ 1)
+ 1))
So you're asking for "The first underscore after (the first underscore after (the first underscore))" - i.e. the third underscore.
something like this should work:
declare #table table (
[file_name] [sysname]
);
declare #pattern [sysname]= N'_test';
insert into #table
([file_name])
values (N'CCA_Type-PROPOSAL_Id-45845_Test1.txt'),
(N'CPA_Type-PROPOSAL_Id-490845_Test2.txt'),
(N'CCA_Type-PROPOSAL_Id-45845_Test_RR1.txt');
select [file_name] as [file_name]
, charindex(#pattern, lower([file_name])) as [character_index_of_pattern]
, substring([file_name], charindex(#pattern, lower([file_name])), len([file_name])) as [desired_output]
from #table;