How to convert a string like ABCDEFG in AbCdEfG in sql - sql

I want o/p of select statement so that it will show alternate letters of given uppercase string in lowercase.
For example if input string is:
ABCDEFG
then output should be:
AbCdEfG

You can create a function containing a simple loop that performs upper/lower casing on your string.
For example in SQL Server:
CREATE FUNCTION [dbo].[AlternateCase]
(
#input_string nvarchar(max)
)
returns nvarchar(max)
as
begin
declare #counter int
declare #result nvarchar (max)
set #counter = 0
set #result = ''
while #counter <= LEN(#input_string)
begin
if #counter % 2 = 0
set #result = #result + lower(substring(#input_string, #counter, 1))
else
set #result = #result + upper(substring(#input_string, #counter, 1))
set #counter = #counter + 1
end
return #result
end
Now you can use the new function in your select statements:
select [dbo].[AlternateCase]('ABCDEFG')
and this select will return:
AbCdEfG

Related

SQL: how to check palindrome of a string without using reverse function?

I'm using SQL Server and I want to check whether the given string is a palindrome or not - but without using the reverse function.
There are multiple ways to achieve this. One of them is to check first and last character, slicing them if they're equal and continuing the process in a loop.
DECLARE #string NVARCHAR(100)
DECLARE #counter INT
SET #string = 'Your string'
SET #counter = LEN(#string)/2
WHILE (#counter > 0)
BEGIN
IF LEFT(#string,1) = RIGHT(#string,1)
BEGIN
SET #string = SUBSTRING(#string,2,len(#string)-2)
SET #counter = #counter - 1
END
ELSE
BEGIN
PRINT ('Given string is not a Palindrome')
BREAK
END
END
IF(#counter = 0)
PRINT ('Given string is a Palindrome')
A select without loops
DECLARE #Test VARCHAR(100)
SELECT #Test = 'qwerewq'
SELECT CASE WHEN LEFT(#Test, LEN(#Test)/2) =
(
SELECT '' + SUBSTRING(RIGHT(#Test, LEN(#Test)/2), number, 1)
FROM master.dbo.spt_values
WHERE type='P' AND number BETWEEN 1 AND LEN(#Test)/2
ORDER BY number DESC
FOR XML PATH('')
)
THEN 1
ELSE 0
END
Here's an example using LEFT and RIGHT. I use the #count variable to change position, then grab the left-most and right-most char:
DECLARE #mystring varchar(100) = 'redivider'
DECLARE #count int = 1
WHILE (#count < LEN(#mystring) / 2) AND #count <> 0
BEGIN
IF (RIGHT(LEFT(#mystring, #count), 1) <> LEFT(RIGHT(#mystring, #count), 1))
SET #count = 0
ELSE SET #count += 1
END
SELECT CASE WHEN #count = 0
THEN 'Not a Palindrome'
ELSE 'Palindrome'
END [Result]

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)