Substring from first half of a delimated string field - sql

I have a Field value in SQL Server's table which contains the path of file, that path is delimited with - character ,What I want is to select the sub-string from beginning (zero index) to last occurrence of that delimited character.
DECLARE #path NVARCHAR(500)
SELECT #path = 'F:\Fruit Seeds-Category Oil\Quality- Fine Seeds',
I need to extract sub-string "F:\Fruit Seeds-Category Oil\Quality" only
My Query
SELECT LEFT(#path, LEN(#path) - CHARINDEX('-',REVERSE(#path)))
What is the best way to do this?

This finds the last index of "-" in the string:
DECLARE #path NVARCHAR(500) = 'F:\Fruit Seeds-Category Oil\Quality- Fine Seeds';
DECLARE #i INT = 1;
DECLARE #ix INT = 0;
WHILE #i > 0
BEGIN
SET #ix = #i;
SET #i = CHARINDEX('-', #Path, #i + 1);
END
SELECT LEFT(#path, #ix - 1)
You can clearly put it inside a function for reuse.

Related

Extract number from a string value

I have a varchar that always come into this format:
'PB' + multiple Leading 0 + Number + Non-Number Character(s).
For example: PB000013452S, PB000013452S3s2fss.
How do I parse the varchar value to get the "Number" (13452) in this case?
Use PATINDEX to find the position of the first number (that isn't 0) and then PATINDEX again to find the position of the first non-numerical character afterwards. Then use SUBSTRING to extract the number:
SELECT SUBSTRING(V.YourString,PI.I,PATINDEX('%[^0-9]%',STUFF(V.YourString,1,PI.I-1,''))-1)
FROM (VALUES('PB000013452S'),('PB000013452S3s2fss'))V(YourString)
CROSS APPLY (VALUES(PATINDEX('%[1-9]%',V.YourString)))PI(I)
I write an algorithme for your problem you can try it and i tested befor it works perfectly but i stored numbers in a table and if you want to concatenate them you can use cursor
declare #x varchar(30) = 'PB000013452S3s2fss' /*your string here*/
declare #_len int = len(#x) /*length of your string */
declare #array table (num varchar(30)) /*table for collecte number*/
declare #c int =1 /*counter*/
declare #_char varchar(1) /* to store one char from your string */
declare #result varchar(30)=''
while #_len>0
begin
set #_char = SUBSTRING(#x,#c,1)
if(#_char in ('1','2','3','4','5','6','7','8','9'))
begin
while #_len>0
begin
set #_char = SUBSTRING(#x,#c,1)
if(#_char in ('0','1','2','3','4','5','6','7','8','9'))
begin
insert into #array values (#_char)
set #c = #c+1
set #_len = #_len-1
end
else
set #_len = 0
end
end
set #c = #c+1
set #_len = #_len-1
end
select * from #array

Substring in sql server

I am trying to extract a substring using the following query. I am not getting the expected result.
DECLARE #st1 varchar(10)
SET #st1 = 'Case # 00548295'
SELECT #st1,ltrim(SUBSTRING(#st1, CHARINDEX('# ', #st1) + 1, LEN(#st1)))
I am getting 005 as the answer. I am trying to extract the integer values after 'Case[space]#[Space]...". My result needs to be 00548295. What is wrong here
You define #st1 as varchar(10), but then try to assign 15 characters ('Case # 00548295') to it. SQL Server silently truncates the data in this case.
Simply increase the size:
DECLARE #st1 varchar(20)
SET #st1 = 'Case # 00548295'
SELECT #st1,ltrim(SUBSTRING(#st1, CHARINDEX('# ', #st1) + 1, LEN(#st1)))
As said by others, you need to increase your variable size. As for your query, instead of substringing out the numbers, you can simply get rid of 'Case # '
DECLARE #st1 varchar(20)
SET #st1 = 'Case # 00548295'
SELECT #st1, REPLACE(#st1, 'Case # ', '')
You did not give your varchar variable enough characters to hold the entire string to begin with.
DECLARE #st1 varchar(20)
SET #st1 = 'Case # 00548295'
SELECT #st1,ltrim(SUBSTRING(#st1, CHARINDEX('# ', #st1) + 1, LEN(#st1)))
-------------------- --------------------
Case # 00548295 00548295
(1 row(s) affected)
Your string value is varchar(10) which is at most 10 characters long. If you select out #st1, you will see it is truncated to 10 characters: 'Case # 005'. You will need to declare this as at least a varchar(15).
In addition to the varchar(15) issue already identified, you can also avoid the "ltrim" and parameterize the delimiter, as shown here:
DECLARE #st1 varchar(15)
declare #delimiter nvarchar(2) = '# ';
declare #delim_len int = DATALENGTH (#delimiter) / 2;
SET #st1 = 'Case # 00548295'
SELECT #st1, SUBSTRING(#st1, CHARINDEX(#delimiter, #st1) + #delim_len, LEN(#st1))
Or take it one step further, and make it into a SQL Function:
if object_id('UFN_STRINGAFTER') is not null
begin
drop function UFN_STRINGAFTER;
end
go
create function dbo.UFN_STRINGAFTER
(
#input nvarchar(max)
,#delimiter nvarchar(max) = '# '
)
returns nvarchar(max)
as
begin
declare #delim_len int = DATALENGTH (#delimiter) / 2;
return SUBSTRING(#input, CHARINDEX(#delimiter, #input) + #delim_len, LEN(#input));
end;
go
select dbo.UFN_STRINGAFTER('Case # 00548295',default);

Inserting/Removing hex padding with SQL Server 2008 R2?

I am working with a database that encodes strings to hex and then pads the entire string with 0's.
Like this:
Origional String: PartitionTest
JUST Hex-encoded Strring: 0x506172746974696f6e54657374
The output I see: 0x50006100720074006900740069006F006E005400650073007400
Is there anyway for me to remove the spaces and decode the final string back to text? AND, how would I then encode that text back to the padded string? I am already converting the string to hex with
SELECT
MASTER.dbo.fn_varbintohexstr(CAST('PartitionTest' AS VARBINARY))
but I don't have a clue how to pad that result out.
Thank you!
EDIT:
As input is varbinary, need to first convert it into varchar to use STUFF.
Declare #input varbinary(128) = 0x50006100720074006900740069006F006E005400650073007400
Declare #Temp as VARCHAR(350)
Set #Temp = CONVERT(VARCHAR(350), #input ,2)
declare #length int
set #length = len(#Temp)
select #length
declare #i int = 3
WHILE #i < #length/2+2
BEGIN
Set #Temp = Stuff(#Temp, #i, 2, '')
set #i = #i +2
END
select '0x' + #Temp

Function returning 2 different results - T-SQL

I have used this site before for help with various things in the past, and in this instance, I couldn't find anything in the search box, so apologies if this exists elsewhere.
In sql server 2005, I have several stored procedures that change various bits of code, and recently we have created a function that adds spaces into a defined string. So in theory, I pass a string into it, and I get a result as blocks of 4. When I run this manually, and define the actual text, it splits fine (I get #### 0000 012 returned) but when I execute the function within the SP, I get #### 0012 0012. Is there any reason why?
I have set a print command to the string before it gets passed into my function, and it prints "####0000012 " and the print after is "#### 0012 0012"
Below is the function code, with no declares:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[udf_addspaces](#string varchar(255),#lengthbetween int)
returns varchar(100)
as
BEGIN
declare #i int, #stringlen float, #output varchar(255), #outputofloop varchar(4)
set #stringlen = LEN(#string)/#lengthbetween
set #output =''
set #i = 0
while #i <= #stringlen
BEGIN
set #outputofloop = left(#string,#lengthbetween)
if #lengthbetween < LEN(#string)
BEGIN
set #string = right(#string,LEN(#string)-#lengthbetween)
END
set #output = #output + #outputofloop +' '
set #i = #i+1
END
return #output
END
Here is the bit of the SP that executes this:
set #Consignment2 = (#Consignment) + rtrim(#Check14)
print #Consignment2
set #Consignment2 = dbo.udf_addspaces(#Consignment2,4)
print #Consignment2
Here are the lines it prints: (Note: #### replaces a 4 digit number, removed for security reasons)
####0000012
#### 0012 0012
Regards,
Luke M
Even though you've defined stringlen as a float, it will be an integer value, because the two values you're dividing are ints.
There's a difference between a char(14) mentioned in your comments, to a varchar(14). The char(14) is guaranteed to be 14 characters long. The varchar may not be.
I think the body of your function could be more succinctly expressed as this...
declare #result varchar(500)
select #result = ''
select
#result = #result
+ substring(#string, number*#lengthBetween+1, #lengthBetween)
+ ' '
from master..spt_values
where type='p'
and number <= (len(#string)/#lengthBetween)
return rtrim(#result)

T-SQL SUBSTRING at certain places

I have the following example.
DECLARE #String varchar(100) = 'GAME_20131011_Set - SET_20131012_Game'
SELECT SUBSTRING(#String,0,CHARINDEX('_',#String))
SELECT SUBSTRING(#String,CHARINDEX('- ',#STRING),CHARINDEX('_',#STRING))
I want to get the words 'GAME' and 'SET' (the first word before the first '_' from both sides of ' - '.
I am getting 'GAME' but having trouble with 'SET'
UPDATE: 'GAME' and 'SET' are just examples, those words may vary.
DECLARE #String1 varchar(100) = 'GAMEE_20131011_Set - SET_20131012_Game' -- Looking for 'GAME' and 'SET'
DECLARE #String2 varchar(100) = 'GAMEE_20131011_Set - SETT_20131012_Game' -- Looking for 'GAMEE' and 'SETT'
DECLARE #String2 varchar(100) = 'GAMEEEEE_20131011_Set - SETTEEEEEEEE_20131012_Game' -- Looking for 'GAMEEEEE' and 'SETTEEEEEEEE'
As long as your two parts will always be separated be a specific character (- in your example), you could try splitting on that value:
DECLARE #String varchar(100) = 'GAME_20131011_Set - SET_20131012_Game'
DECLARE #Left varchar(100),
#Right varchar(100)
-- split into two strings based on a delimeter
SELECT #Left = RTRIM(SUBSTRING(#String, 0, CHARINDEX('-',#String)))
SELECT #Right = LTRIM(SUBSTRING(#String, CHARINDEX('-',#String)+1, LEN(#String)))
-- handle the strings individually
SELECT SUBSTRING(#Left, 0, CHARINDEX('_', #Left))
SELECT SUBSTRING(#Right, 0, CHARINDEX('_', #Right))
-- Outputs:
-- GAME
-- SET
Here's a SQLFiddle example of this: http://sqlfiddle.com/#!3/d41d8/22594
The issue that you are running into with your original query is that you are specifying CHARINDEX('- ', #String) for your start index, which will include - in any substring starting at that point. Also, with CHARINDEX('_',#STRING) for your length parameter, you will always end up with the index of the first _ character in the string.
By splitting the original string in two, you avoid these problems.
Try this
SELECT SUBSTRING(#String,0,CHARINDEX('_',#String))
SELECT SUBSTRING(#String,CHARINDEX('- ',#STRING)+1, CHARINDEX('_',#STRING)-1)
charindex takes an optional third parameter that says which poistion in the string to start the search from. You could roll this into one statement, but it's easier to read with three
Declare #start int = charindex('-', #string) + 2;
Declare #end int = charindex('_', #string, #start);
Select substring(#string, #start, #end - #start);
Example SQLFiddle