I tried to Insert a string within another string using STUFF.
DECLARE #Number VARCHAR(100) = '12345'
SELECT STUFF(#Number, 3, 0, '6') -- Add value in 3rd Position, Returns '126345'
I tried to append the value at the end
SELECT STUFF(#Number, 6, 0, '6') -- Add value in 6th Position
-- Actual length is 5, So it Returns 'NULL'
Expected Output:
123456
I tried using STUFF for simple statement. But not able to append string at the end. Can anyone help me to do in any other simple way?
From here:
The second paramter is an integer value that specifies the location to
start deletion and insertion. If start or length is negative, a null
string is returned. If start is longer than the first
character_expression, a null string is returned. start can be of type
bigint.
This query :
DECLARE #Number VARCHAR(100) = '12345'
SELECT STUFF(#Number, 6, 0, '6')
return NULL because there is only 5 characters.
If you want append string at the end just concat that string using + operator.
DECLARE #Number VARCHAR(100) = '12345'
SELECT #Number + '6'
You can use CONCAT to append strings one after the other. They will be appended in the order in which they are passed to the function:
DECLARE #Number VARCHAR(100) = '12345'
select concat(#Number,'6')
You can also use the '+' operator for this purpose. However, if one the strings being appended is NULL, the result will also be NULL using '+', whereas the NULL string is treated as a blank string by CONCAT.
select concat(#Number,null,6) -- = '123456'
select #Number + null + 6 -- == null
If the position to insert is not fixed, you can use a CASE statement along with STUFF and CONCAT to either insert into or append in a single statement, like so:
declare #number varchar(100) = '12345'
declare #pos int = 6
declare #append varchar(100) = '6'
select
case
when #pos < len(#number) then stuff(#number,#pos,0,#append)
else concat(#number,#append)
end result
As a hack you can do this,
SELECT STUFF(#Number, 5, 1, '56')
Related
Anyone able to advice why does my max value return smaller value?
DECLARE #SalesYear as nvarchar(max),
#SalesPeriod as nvarchar(max)
SET #SalesYear = 2020
SET #SalesPeriod = '5,6,7,8,10'
BEGIN
DECLARE #Split char(1)=',',
#X xml
SELECT #X = CONVERT(xml, ' <root> <myvalue>' +
REPLACE(#SalesPeriod,#Split,'</myvalue> <myvalue>') + '</myvalue> </root>')
IF (OBJECT_ID('tempdb..#breakdown') IS NOT NULL)
BEGIN
DROP TABLE #breakdown
END
SELECT T.c.value('.','varchar(20)') breakdown
INTO #breakdown
FROM #X.nodes('/root/myvalue') T(c)
END
SELECT MAX(breakdown)
FROM #breakdown
It returns max value as '8' instead of '10'. Anything wrong with my code?
I would change the type INT instead of varchar as SalesPeriod seems have a numerical values :
SELECT T.c.value('.','INT') AS breakdown INTO #breakdown
FROM #X.nodes('/root/myvalue') T(c)
So, string value comparisons 8 will be higher than 10, You can check :
select case when '8' > '10' then 1 else 0 end
If you change the type (remove quotes), you will see right flagging. So, i would recommend to use appropriate datatype.
how to select next n letters after one specific letter using function in sql server by giving function name,specific word, no of letters next to be printed
for eg : function name, ' specific letter', no of letters to be printed next to specific letter
Mixture of CHARINDEX with SUBSTRING if on SQL Server.
DECLARE #Text VARCHAR(100) = 'The cat is under the table.'
DECLARE #CharToSearch CHAR = 's'
DECLARE #CharactersToRetrieve INT = 5
SELECT
CharacterPosition = CHARINDEX(#CharToSearch, #Text),
TrimmedString = SUBSTRING(
#Text,
CHARINDEX(#CharToSearch, #Text) + 1,
#CharactersToRetrieve)
Result:
CharacterPosition TrimmedString
10 unde
If you are using MySQL try the following query
select substring(user_name,locate("a",user_name)+1,2) from user_details where user_id=3;
In the above query, I am trying to fetch 2 letters after first occurrence of the letter 'a' from user_name field of my user_details table where user_id is 3.
Modify the query as per your need.
create function new(#text varchar(50),#CharToSearch char,#CharactersToRetrieve int)
Returns varchar(100)
AS
BEGIN
DECLARE #new varchar(20)
DECLARE #CharToSearchs int
select #CharToSearchs= CHARINDEX(#CharToSearch, #text);
set #new=SUBSTRING(#text,#CharToSearchs+1,#CharactersToRetrieve)
RETURN #new
END
I'm trying to write a SQL Server 2008 R2 statement in a stored procedure that takes a 9-character SKU value as input, and has to grab certain character values in specific positions of that input field and concatenate them to a value.
I wrote the following but it doesn't seem to be working, though that could just be me. It seems to make sense on paper...
IF NOT #SKU = '' BEGIN
DECLARE #StringPos SMALLINT = 1, #StringLen SMALLINT, #ColNum SMALLINT, #ItemVal VARCHAR(10)
SET #StringLen = LEN(#RecallSortMode)
WHILE #StringPos <= #StringLen BEGIN
SET #ColNum = SUBSTRING(#RecallSortMode, #StringPos, 1)
SET #ItemVal += SUBSTRING(#SKU, #ColNum, 1)
SET #StringPos = #StringPos + 1
END
PRINT 'Item Val: ' + #ItemVal
END
So, if the columns I need are 1, 2 and 9 the value of #RecallSortMode would be 129 and if the value of #SKU is 9 characters long and is 987654321 I'm looking for the statement to return an #ItemVal of 981.
Does this work or am I doing something wrong? It seems to compile OK but I get back nothing from it.
Thanks
Below is some test SQL. IsNumeric is saying the substring of 05031, is numeric, but fails when it tries to convert it to an actual number because of the ,. Is this a bug in SQL?
DECLARE #Str NVARCHAR(20)
SET #Str = 'XYZ 505031, some text'
SELECT CASE WHEN ISNUMERIC(SUBSTRING(#Str,6,7)) = 1 THEN CONVERT(int,SUBSTRING(#Str,6,7)) ELSE 0 END, SUBSTRING(#Str,6,7)
you should use try_cast instead, because ISNUMERIC evaluates to 1 for 5031,
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL).
DECLARE #Str NVARCHAR(20)
SET #Str = 'XYZ 505031, some text'
SELECT
CASE
WHEN TRY_CAST(SUBSTRING(#Str,6,7) AS DECIMAL(10,2)) IS NOT NULL
THEN CONVERT(int,SUBSTRING(#Str,6,7))
ELSE 0
END,
SUBSTRING(#Str,6,7)
If 2012+, you can use Try_Convert(). We use MONEY becase the this will convert the leading zero, and then we convert to int
Example
DECLARE #Str NVARCHAR(20)
SET #Str = 'XYZ 505031, some text'
SELECT AsInt = IsNull(try_convert(int,try_convert(money,SUBSTRING(#Str,6,7))),0)
, AsStr = SUBSTRING(#Str,6,7)
Returns
AsInt AsStr
5031 05031,
This is because your substring is also pulling a comma in the end.
SELECT SUBSTRING(#Str, 6, 7);
is resulting:
05031,
Whereas,
SELECT SUBSTRING(#Str, 6, 5);
is resulting:
05031
And
SELECT CASE WHEN ISNUMERIC(SUBSTRING(#Str,6,5)) = 1 THEN CONVERT(int,SUBSTRING(#Str,6,5)) ELSE 0 END, SUBSTRING(#Str,6,5)
is resulting:
5031 | 05031
I am using a function that I found here and else where on the internet to try and strip illegal characters from a field.
Create Function [epacube].[StripSpecs](#myString varchar(500),
#invalidChars varchar(100)) RETURNS varchar(500) AS Begin
While PatIndex(#invalidChars, #myString) > 0
Set #myString = Stuff(#myString, PatIndex(#invalidChars, #myString), 1, '')
Return #myString End
in my table I have set my field value to be: set DATA_NAME = 'Pro$d)uc^t'
If I run this query:
SELECT epacube.StripSpecs (
DATA_NAME
,'%$%') FROM TABLE_DATA
It works and I get a value returned of Prod)uc^t
However, if I add another special character, it no longer works:
SELECT epacube.StripSpecs (
DATA_NAME
,'%$)%') FROM TABLE_DATA
returns my original value Pro$d)uc^t
Does anyone have any suggestion for accomplishing what I need to do?
EDIT
As per the answer below here is the code that worked:
Create Function [epacube].[StripSpecs](#myString varchar(500), #invalidChars varchar(100))
RETURNS varchar(500) AS
Begin
While PatIndex('%[' + #invalidChars + ']%', #myString) > 0
Set #myString = Stuff(#myString, PatIndex('%[' + #invalidChars + ']%', #myString), 1, '')
Return #myString
End
As with LIKE, if you want to specify that one of a set of characters should match, use [] to enclose the set.
SELECT epacube.StripSpecs (
DATA_NAME
,'%[$)]%') FROM TABLE_DATA
Although, personally, given the descriptions of the function and parameters, I'd add the %[ and ]% in StripSpecs, and let the caller just give a list of characters (if you don't want to support any other type of pattern being specified)