SQL REPLACE special characters with value from another table - sql

All,
I am trying to replace the special characters in a string with the URL
encoding values to which they correspond. Below is some example code I have
been working with.
Thanks for the help.
create table #url_encoding_lookup(character varchar(10), code varchar (20))
insert into #url_encoding_lookup (character, code)
values
('!', '%21'),
('"', '%22'),
('#', '%23'),
('$', '%24'),
('%', '%25'),
('&', '%26'),
('''', '%27'),
('(', '%28'),
(')', '%29'),
('*', '%2A'),
('+', '%2B'),
(',', '%2C'),
('-', '%2D'),
('.', '%2E'),
('/', '%2F')
Create table #data
(string varchar (200))
insert into #data
values
('Jim (BoB)'),
('Will''s Place'),
('Auto-Mart')
select * from #data
select * from #url_encoding_lookup
desired results would be
Jim %28Bob%29
Will%27s Place
Auto%2DMart

Create procedure
BEGIN
DECLARE _end BOOLEAN DEFAULT FALSE;
DECLARE _result CHAR(200) DEFAULT str;
DECLARE _find VARCHAR(32);
DECLARE _replace VARCHAR(32);
DECLARE _cur CURSOR FOR SELECT _character, _code FROM url_encoding_lookup;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET _end = TRUE;
OPEN _cur;
_loop: LOOP
FETCH _cur INTO _find, _replace;
IF _end THEN
LEAVE _loop;
END IF;
SET _result = REPLACE(_result, _find, _replace);
END LOOP _loop;
CLOSE _cur;
RETURN _result;
END
Then
SELECT _replace_chars(name) FROM `data`
Result
Jim %28BoB%29
Will%27s Place
Auto%2DMart

ALTER FUNCTION [dbo].[udf_ReplaceYouCoded]
(
#the_string nvarchar(max)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
declare #temp_field nvarchar(max)
create table #url_encoding_lookup(character varchar(10), code varchar (20))
insert into #url_encoding_lookup (character, code)
values
('!', '%21'),
('"', '%22'),
('#', '%23'),
('$', '%24'),
('%', '%25'),
('&', '%26'),
('''', '%27'),
('(', '%28'),
(')', '%29'),
('*', '%2A'),
('+', '%2B'),
(',', '%2C'),
('-', '%2D'),
('.', '%2E'),
('/', '%2F')
declare #x as int
set #x = 1
--LOOP #the_string
while #i < len(#the_string)
if(substring(#the_string,x,1) = (select character from #url_encoding_lookup where character = substring(#the_string,x,1)))
begin
#temp_field = #temp_field + (select code from #url_encoding_lookup where character = substring(#the_string,x,1))
end
else
begin
#temp_field = #temp_field + substring(#the_string,x,1)
end
select #x = #x + 1
end
RETURN #temp_field
END

ALTER function [dbo].[udf_ReplaceSpecialChars]
(#s varchar(256))
returns varchar(256)
as
begin
-- declare #s varchar(256) set #s = 'Jim (P)' --test
if #s is null
return null
declare #s2 varchar(256)
set #s2 = '' --set variable to empty string. ready to recieve values
declare #l int
set #l = len(#s) --determin the number of characters in #s
declare #p int
set #p = 1 --set beginning string position
while #p <= #l begin
declare #c int
set #c = ascii(substring(#s, #p, 1)) --find the ascii number for 1st
character
declare #nc varchar(256)
set #nc = (select code from url_encoding_lookup where ascii_code = #c) --
get corresponding URL encoding string from lookup table
if #c between 33 and 47 or #c between 58 and 64 or #c between 91 and 96
or #c between 123 and 255 --when looping through each character, if special
character
set #s2 = #s2 + #nc --then use string from lookup table
else if #c = 32 or #c between 48 and 57 or #c between 65 and 90 or #c
between 97 and 122 --if character is not special
set #s2 = #s2 + char(#c) --then find char value of character
set #p = #p + 1 --set position to next charachter for loop to look at
end
if len(#s2) = 0
return null
return #s2 --return rebuilt string
end

You can replace the special characters using the following regular expression [\u0100-\uffff]
select regexp_replace(column, '[\u0100-\uffff]', '')

Related

Order By Clause return wrong order when there are special characters in record set

I am using SQL server. I am fetching student information from database. I order by lastname and then first name like ORDER BY lastname, firstname it works until I have simple data. Issue occurs when there is '~' or any other character in name occur. It disturb order.
UPDATE
Here is what I am getting currently
and on front end I have this
Expectation is 2 and 3 should be after 4 and 5 as k comes first order then Γ±
Use Collate with your query. Hope that can help! Like:
SELECT FIRSTNAME, LASTNAME
FROM TABLE
ORDER BY FIRSTNAME Collate SQL_Latin1_General_CP1253_CI_AI
Make this function in sql server-----
CREATE FUNCTION dbo.RemoveSpecialChars (#s VARCHAR(256))
RETURNS VARCHAR(256)
WITH schemabinding
BEGIN
IF #s IS NULL
RETURN NULL
DECLARE #s2 VARCHAR(256)
SET #s2 = ''
DECLARE #l INT
SET #l = len(#s)
DECLARE #p INT
SET #p = 1
WHILE #p <= #l
BEGIN
DECLARE #c INT
SET #c = ascii(substring(#s, #p, 1))
IF #c BETWEEN 48
AND 57
OR #c BETWEEN 65
AND 90
OR #c BETWEEN 97
AND 122
SET #s2 = #s2 + CHAR(#c)
SET #p = #p + 1
END
IF len(#s2) = 0
RETURN NULL
RETURN #s2
END
now you can order by like ---
SELECT *
FROM yourtablename
ORDER BY dbo.RemoveSpecialChars(yourcolumnname)

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]

How to replace this special character at all the places

I tried the following the ways, but result could not be as per requirement( I mean getting same after running replace query). how to replace all the places that special character only?
Here is the Query.
select
REPLACE(description,'β€š'COLLATE Latin1_General_BIN, N'β€š')
from Zstandars_25Feb2015 where Colname = 56
Result:
.
....the form 𝘹 + 𝘱 = 𝘲 and 𝘱𝘹 = 𝘲 for cases in which 𝘱, 𝘲 and
𝘹 are all nonnegative ..........
whats the type of your description field?
if its varchar, you shouldnt face any problem. I have run your query in my test table and i didnt get such a error, it might be something with your collation, remove collate and try it again or change the collation to something else.
-- Removes special characters from a string value.
-- All characters except 0-9, a-z and A-Z are removed and
-- the remaining characters are returned.
-- Author: Christian d'Heureuse, www.source-code.biz
create function dbo.RemoveSpecialChars (#s varchar(256)) returns varchar(256)
with schemabinding
begin
if #s is null
return null
declare #s2 varchar(256)
set #s2 = ''
declare #l int
set #l = len(#s)
declare #p int
set #p = 1
while #p <= #l begin
declare #c int
set #c = ascii(substring(#s, #p, 1))
if #c between 48 and 57 or #c between 65 and 90 or #c between 97 and 122
set #s2 = #s2 + char(#c)
set #p = #p + 1
end
if len(#s2) = 0
return null
return #s2
end
By keeping N, I am able to fetch the data..
select
REPLACE(description,N'β€š'COLLATE Latin1_General_BIN, N'β€š')
from Zstandars_25Feb2015 where Colname = 56
Thanks all for the help.

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)