How to replace string in SQL from index to index - sql

Hi guys can someone help me to write this?
DECLARE #STR VARCHAR(55) = 'Name';
SELECT // SOME LOGIC
RESULT => 'NXXE'
I would like this logic to be generalized to replace every string except the first and last character.

if dynamic data masking is not an answer you can use query below :
DECLARE #str VARCHAR(100) = 'yourstring'
SELECT UPPER(LEFT(#str,1) + REPLICATE('x',LEN(#str) -2)+ RIGHT(#str,1))

This is what you want
DECLARE #STR VARCHAR(55) = 'Name';
declare #i int
Set #i = 0
while #i <= len(#STR )
begin
select #i = #i + 1
if(#i>1 AND #i<len(#STR ))
select #STR = STUFF(#STR , #i, 1, 'X')
END
SELECT #STR

Related

SQL Query to remove common string

#strA and #strB are two variables
#strA = "055367911126753316"
#strB = "00055367"
how to find the common part "055367" and remove it from string A, using SQL server query without looping?
the result should be "911126753316"
be noted that always string A begin by the end part of string B
You can use replace in sql server as below:
declare #strA varchar(50) = '055367911126753316'
declare #strB varchar(50) = '00055367'
select replace(#strA,right(#strB,len(#strB)-2),'')
If it is in different columns in a table you can use as below:
create table #yourcolumns ( cola varchar(50), colb varchar(50))
insert into #yourcolumns (cola, colb) values
('055367911126753316', '00055367')
select replace(cola,right(colb,len(colb)-2),'') from #yourcolumns
I think we need to go for substring in your case as you are looking for startswith
select SUBSTRING(cola,CHARINDEX(LEFT(REVERSE(colb),1),cola)+1,len(cola)) from #yourcolumns
Try This, works dynamically.
declare #StrA Nvarchar(250)='055367911126753316',#StrB Nvarchar(250)='0055367'
select right(#StrA,len(#strA)-PATINDEX('%[^'+#StrB+']%',#strA)+1)
It YES with looping, But it work....
create function MyFn (#A nvarchar(max), #B nvarchar(max))
returns nvarchar(max)
as
begin
declare #I int, #L int, #SUB nvarchar(max)
select #I = 1, #L = len(#B)
while #I<#L begin
set #SUB = substring(#B,#I,#L-#I+1)
if charindex(#SUB,#A,1) > 0 begin
set #A = replace(#A, #SUB, '')
break
end
set #I = #I + 1
end
return #A
end
If each string A starts with 000 and each string b just contains one 0 this should retrieve the correct result
WITH CTE AS (SELECT [StringA], [StringB],REPLACE([StringB], '000', '0') [tbd]
FROM YourTable)
SELECT REPLACE(YourTable.[StringA], CTE.[tbd], ''), YourTable.[StringA]
FROM YourTable
JOIN CTE ON YourTable.[StringA]= CTE.[StringA]
DECLARE #strA varchar(50) = '055367911126753316'
DECLARE #strB varchar(50) = '00055367'
SET #strA=(SELECT REVERSE(SUBSTRING(#strA, PATINDEX('%[^0 ]%', #strA + ' '), LEN(#strA))))
SET #strB=(SELECT REVERSE(SUBSTRING(#strB, PATINDEX('%[^0 ]%', #strB + ' '), LEN(#strB))))
SELECT #strA String ,#strB StringtoSearch,REVERSE(SUBSTRING(#strA,0,CHARINDEX(RIGHT(#strA,LEN(#strB)),#strA)))ExpectedOutput
Output
ExpectedOutput
---------------
911126753316

How to find a special characters in a string and replace it with a space in SQL?

I have contact_firstname column which has some special characters like (#,&,-,_, etc) in the data stored in that column. I want to first find all those special characters in each record and replace those characters with a space. I found a query on this website which helps identify the special characters but I am not sure how to find charindex of each special character in the below string and replace it with a space.
DECLARE #MyString VARCHAR(100)
SET #MyString = '!Char$Fox#'
IF (#MyString LIKE '%[^a-zA-Z0-9]%')
BEGIN
PRINT 'Contains "special" characters'
END
I think you have to loop, as Tab Alleman mentioned:
declare #MyString varchar(100) = '!Char$Fox#'
declare #i int = 0
declare #char varchar(1)
declare #len int = LEN(#MyString)
declare #result varchar(100) = ''
while #i < #len
begin
set #char = SUBSTRING(#MyString, #i, 1)
if #char like '%[^a-zA-Z0-9]%'
begin
set #char = ' '
end
set #result = #result + #char
set #i = #i + 1
end
select #result
You can also do this:
DECLARE #InvalidChars VARCHAR(100)
DECLARE #MyString VARCHAR(100)
SET #InvalidChars = '!$#'
SET #MyString = '!Char$Fox#'
;WITH CTE AS
(
SELECT SUBSTRING(#InvalidChars, 1, 1) AS [String], 1 AS [Start], 1 AS [Counter]
UNION ALL
SELECT SUBSTRING(#InvalidChars, [Start] + 1, 1) AS [String], [Start] + 1, [Counter] + 1
FROM CTE
WHERE [Counter] < LEN(#InvalidChars)
)
SELECT #MyString = REPLACE(#MyString, CTE.[String], ' ') FROM CTE
SELECT #MyString
Result:
Char Fox
This is a combination of solutions found here:
How to Replace Multiple Characters in SQL?
T-SQL: Opposite to string concatenation - how to split string into multiple records [duplicate]

Why does this TSql return a blank or null value?

Why does the #result value in the code below print out a blank string? I would expect it to concatenate with the previous result.
DECLARE #size int
DECLARE #string nvarchar(10)
DECLARE #result nvarchar(10)
SELECT #string = '12345abc123'
DECLARE #count int, #total int
SELECT
#total = LEN(#string),
#count = 1
WHILE #count <= #total
BEGIN
SELECT #result = SUBSTRING(#string, #count, 1) + '-'+ #result
SELECT #count = #count + 1
PRINT #result
END
You never initialized #result, so it defaults to an sql null. SQL nulls are contagious poison, so when you do
SELECT #result = .... + #result
You're actually doing
SELECT #result = ... + null
and #result simply remains null
Initializing the value to an empty string solves your problem:
SET #result = ''
It is returning a blank because you are concatenating the substring with #result, which initially is NULL.
Try setting #result to an empty string like this this:
SELECT #string = '12345abc123', #result = ''
you have to initialize #result variable
Declare it like this
DECLARE #result nvarchar(10) = ''
this should work

How to toggle case of Entire string in sql

I want to toggle case of entire string.
I am able to do for characters, not for string.
DECLARE #Char AS VARCHAR(1)
SET #Char='a'
IF ASCII(#Char)>=97 AND ASCII(#Char) <=122
PRINT UPPER(#Char)
IF ASCII(#Char)>=65 AND ASCII(#Char) <=90
PRINT LOWER(#Char)
How, I can change case for entire string?
For Ex. "AbCdE", I want to change it to "aBcDe".
You can do it by creating functions:
First make function for one character:
CREATE FUNCTION ToggleChar
(
#Char VARCHAR(1)
)
RETURNS VARCHAR(1)
AS
BEGIN
RETURN CHAR(ASCII(UPPER(#Char))+ASCII(LOWER(#Char))-ASCII(#Char))
END
Then, create function for string:
CREATE FUNCTION ToggleCase
(
#Str VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #ResultStr VARCHAR(MAX)
SET #ResultStr=''
WHILE ( #Str<>'')
BEGIN
SET #ResultStr=#ResultStr + [dbo].[ToggleChar](#Str)
SET #Str= SUBSTRING(#Str,2,LEN(#Str))
END
RETURN #ResultStr
END
Now, use this function to toggle string.
SELECT dbo.ToggleCase('AbCdE') AS ToggleString
Try this:
DECLARE #Name VARCHAR(10) = 'SaMplE'
DECLARE #Count INT = 1
WHILE #Count <= LEN(#Name)
BEGIN
SET #Name = STUFF(#Name, #Count, 1,
CASE
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 97 AND 122 THEN
UPPER(SUBSTRING(#Name,#Count,1))
WHEN ASCII(SUBSTRING(#Name,#Count,1)) BETWEEN 65 AND 90 THEN
LOWER(SUBSTRING(#Name,#Count,1))
END)
SET #Count = #Count + 1
END
SELECT #Name

How to change case in string

My table has one column that contain strings like: ” HRM_APPLICATION_DELAY_IN”
I want to perform bellow operations on each row on this column
convert to lower case
remove underscore “_”
change case (convert to upper case) of the character after the underscore like: ” hrm_Application_Delay_In”
Need help for conversion. Thanks for advance
Here is a function to achieve it:
create function f_test
(
#a varchar(max)
)
returns varchar(max)
as
begin
set #a = lower(#a)
while #a LIKE '%\_%' ESCAPE '\'
begin
select #a = stuff(#a, v, 2, upper(substring(#a, v+1,1)))
from (select charindex('_', #a) v) a
end
return #a
end
Example:
select dbo.f_test( HRM_APPLICATION_DELAY_IN')
Result:
hrmApplicationDelayIn
To update your table here is an example how to write the syntax with the function:
UPDATE <yourtable>
SET <yourcolumn> = dbo.f_test(col)
WHERE <yourcolumn> LIKE '%\_%' ESCAPE '\'
For a variable this is overkill, but I'm using this to demonstrate a pattern
declare #str varchar(100) = 'HRM_APPLICATION_DELAY_IN';
;with c(one,last,rest) as (
select cast(lower(left(#str,1)) as varchar(max)),
left(#str,1), stuff(lower(#str),1,1,'')
union all
select one+case when last='_'
then upper(left(rest,1))
else left(rest,1) end,
left(rest,1), stuff(rest,1,1,'')
from c
where rest > ''
)
select max(one)
from c;
That can be extended to a column in a table
-- Sample table
declare #tbl table (
id int identity not null primary key clustered,
str varchar(100)
);
insert #tbl values
('HRM_APPLICATION_DELAY_IN'),
('HRM_APPLICATION_DELAY_OUT'),
('_HRM_APPLICATION_DELAY_OUT'),
(''),
(null),
('abc<de_fg>hi');
-- the query
;with c(id,one,last,rest) as (
select id,cast(lower(left(str,1)) as varchar(max)),
left(str,1), stuff(lower(str),1,1,'')
from #tbl
union all
select id,one+case when last='_'
then upper(left(rest,1))
else left(rest,1) end,
left(rest,1), stuff(rest,1,1,'')
from c
where rest > ''
)
select id,max(one)
from c
group by id
option (maxrecursion 0);
-- result
ID COLUMN_1
1 hrm_Application_Delay_In
2 hrm_Application_Delay_Out
3 _Hrm_Application_Delay_Out
4
5 (null)
6 abc<de_Fg>hi
select
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(lower('HRM_APPLICATION_DELAY_IN'),'_a','A'),'_b','B'),'_c','C'),'_d','D'),'_e','E'),'_f','F'),
'_g','G'),'_h','H'),'_i','I'),'_j','J'),'_k','K'),'_l','L'),
'_m','M'),'_n','N'),'_o','O'),'_p','P'),'_q','Q'),'_r','R'),
'_s','S'),'_t','T'),'_u','U'),'_v','V'),'_w','W'),'_x','X'),
'_y','Y'),'_z','Z'),'_','')
Bellow two steps can solve problem,as example i use sys.table.user can use any one
declare #Ret varchar(8000), #RetVal varchar(8000), #i int, #count int = 1;
declare #c varchar(10), #Text varchar(8000), #PrevCase varchar, #ModPrefix varchar(10);
DECLARE #FileDataTable TABLE(TableName varchar(200))
INSERT INTO #FileDataTable
select name FROM sys.tables where object_name(object_id) not like 'sys%' order by name
SET #ModPrefix = 'Pur'
DECLARE crsTablesTruncIns CURSOR
FOR select TableName FROM #FileDataTable
OPEN crsTablesTruncIns
FETCH NEXT FROM crsTablesTruncIns INTO #Text
WHILE ##FETCH_STATUS = 0
BEGIN
SET #RetVal = '';
select #i=1, #Ret = '';
while (#i <= len(#Text))
begin
SET #c = substring(#Text,#i,1)
--SET #Ret = #Ret + case when #Reset=1 then UPPER(#c) else LOWER(#c)
IF(#PrevCase = '_' OR #i = 1)
SET #Ret = UPPER(#c)
ELSE
SET #Ret = LOWER(#c)
--#Reset = case when #c like '[a-zA-Z]' then 0 else 1 end,
if(#c like '[a-zA-Z]')
SET #RetVal = #RetVal + #Ret
if(#c = '_')
SET #PrevCase = '_'
else
SET #PrevCase = ''
SET #i = #i +1
end
SET #RetVal = #ModPrefix + #RetVal
print cast(#count as varchar) + ' ' + #RetVal
SET #count = #count + 1
EXEC sp_RENAME #Text , #RetVal
SET #RetVal = ''
FETCH NEXT FROM crsTablesTruncIns INTO #Text
END
CLOSE crsTablesTruncIns
DEALLOCATE crsTablesTruncIns
I'd like to show you my nice and simple solution. It uses Tally function to split the string by pattern, in our case by underscope. For understanding Tally functions, read this article.
So, this is how my tally function looks like:
CREATE FUNCTION [dbo].[tvf_xt_tally_split](
#String NVARCHAR(max)
,#Delim CHAR(1))
RETURNS TABLE
as
return
(
WITH Tally AS (SELECT top (select isnull(LEN(#String),100)) n = ROW_NUMBER() OVER(ORDER BY [name]) from master.dbo.syscolumns)
(
SELECT LTRIM(RTRIM(SUBSTRING(#Delim + #String + #Delim,N+1,CHARINDEX(#Delim,#Delim + #String + #Delim,N+1)-N-1))) Value, N as Ix
FROM Tally
WHERE N < LEN(#Delim + #String + #Delim)
AND SUBSTRING(#Delim + #String + #Delim,N,1) = #Delim
)
)
This function returns a table, where each row represents part of string between #Delim (in our case between underscopes). Rest of the work is simple, just cobination of LEFT, RIGHT, LEN, UPPER and LOWER functions.
declare #string varchar(max)
set #string = ' HRM_APPLICATION_DELAY_IN'
-- convert to lower case
set #string = LOWER(#string)
declare #output varchar(max)
-- build string
select #output = coalesce(#output + '_','') +
UPPER(left(Value,1)) + RIGHT(Value, LEN(Value) - 1)
from dbo.tvf_xt_tally_split(#string, '_')
-- lower first char
select left(lower(#output),1) + RIGHT(#output, LEN(#output) - 1)