SQL Replace all characters in a string - sql

Is there any SQL statements to replace everything in a string with an 'X'. The strings aren't all the same length so it makes it a bit tricky. I haven't been able to find anything that does this except the function below but it takes a long time when I pass in 'a-z0-9' since I have to search on all of those but I really just want to replace everything no matter what it is.
[dbo].[cfn_StripCharacters]
(
#String NVARCHAR(MAX),
#MatchExpression VARCHAR(255)='a-z0-9'
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
SET #MatchExpression = '%['+#MatchExpression+']%'
WHILE PatIndex(#MatchExpression, #String) > 0
SET #String = Stuff(#String, PatIndex(#MatchExpression, #String), 1, 'X')
RETURN #String
For example the data column looks like this and I want to replace the whole string with x's:
975g -> XXXX
ryth5 -> XXXXX
1234vvsdf5 -> XXXXXXXXXX
test1234 -> XXXXXXXX

If this is SQL Server, you can use the REPLICATE function and simply replicate x the LEN() of the string.
SELECT REPLICATE('x', LEN(#String))
sqlFiddle
Edit - Looks like this is also available in MySQL via REPEAT() but I haven't tested

You can use Replicate and Len functions to replace all characters.
declare #str varchar(20)
set #str = 'abc'
select #str = REPLICATE('X', len(#str))
select #str

There are no built in functions to do it. You can write a CLR function that does a regex replace, though.

Related

Remove phone numbers from text in SQL Server

In a text column in SQL Server, there are personal phone numbers which I want to replace with # for each numbers. Please see examples below:
'07555815825'
'CALL ME ON 07585815826'
'TEXT 07545815826 TEST'
'TEXT 07545815826 TEST its 2020'
I have tried cross apply and string split but cannot get the desired results.
Below are the desired results:
'###########'
'CALL ME ON ###########'
'TEXT ########### TEST'
'TEXT ########### TEST its 2020'
Your sample data has exactly 11-digit phone numbers and only one phone number per text. With these constraints, you can use stuff():
select v.text,
stuff(text, patindex('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%', text + '00000000000'), 11, 'XXXXXXXXXXX')
from (values ('07555815825'),
('CALL ME ON 07585815826'),
('TEXT 07545815826 TEST'),
('TEXT 07545815826 TEST its 2020')
) v(text);
Note: This also handles texts that have no phone numbers.
You can not do it as you want using native tql syntax because you don't have a builtin regex feature, but you can use other builtin functions to create something similar to regex.
here is a function,I found it in stackoverflow when I had the same need, that you can add to your solution that can help you with your need
CREATE FUNCTION dbo.fn_ReplaceWithPattern
(
#InputString VARCHAR(MAX),
#Pattern VARCHAR(MAX),
#ReplaceString VARCHAR(MAX),
#ReplaceLength INT = 1
)
RETURNS VARCHAR(MAX)
BEGIN
DECLARE #Index INT;
set #Index = patindex(#Pattern, #InputString);
while #Index > 0
begin
--replace matching character at index
set #InputString = stuff(#InputString, patindex(#Pattern, #InputString), #ReplaceLength, #ReplaceString);
set #Index = patindex(#Pattern, #InputString);
end;
return #InputString;
END;
To use it, you do so
declare #textString VARCHAR(250) = '07555815825
CALL ME ON 07585815826
TEXT 07545815826 TEST
TEXT 07545815826 TEST its 2020'
--select Replace(#textString, Substring(#textString, PatIndex('%[0-9]%', #textString), 1), '')
select dbo.fn_ReplaceWithPattern(#textString,'%[0-9]%','',1)
output
if your data is stored in a table, and you need to update its value, you do so
update TableA
set ColumnX = dbo.fn_ReplaceWithPattern(ColumnX,'%[0-9]%','',1)
If you need it just in your select statment, you use this syntaxe
select dbo.fn_ReplaceWithPattern(ColumnX,'%[0-9]%','',1) as SanitizedValue
from TableA

Replace pattern with value

How can I replace the $SV### value in this string example if I don't know what the numbers following will be? Or even just get the 1234544 into another string variable.
I tried this but it doesn't replace anything:
declare #string varchar(100) = 'F4 Obstructed reach beyond. [$SV1234544" provided.]'
SELECT REPLACE(#string,PATINDEX('%$SV[0-9+]%',#string),'test')
Thank you!
The below code will work with the expectation that the number will always be prefixed with "$SV". It goes through a series of iterations to locate the numeric value after "$SV" and then replaces the "$SV" and the numeric number with whatever text you want it replaced with. This code uses the substring, patindex, concat, and replace functions.
DECLARE #string varchar(100) = 'F4 Obstructed reach beyond. [$SV1234544" provided.]'
DECLARE #SubString Varchar(100) = SUBSTRING(#string, PATINDEX('%$SV[0-9]%', #string), LEN(#string))
SELECT REPLACE(#string,CONCAT('$SV',LEFT(SUBSTRING(#SubString, PATINDEX('%[0-9.-]%', #SubString), 8000),PATINDEX('%[^0-9.-]%', SUBSTRING(#SubString, PATINDEX('%[0-9.-]%', #SubString), 8000) + 'X') -1)),'test')

Remove characters before and after string SQL

I would like to remove all characters before and after a string in the select statement.
In the example below I would like to remove everything before and including /Supply> and after and including >/
Note the remaining part will be a fixed number of characters.
Any help would be much appreciated
Eg.
abs/Supply>hhfhjgglldppprrr>/llllllldsfsjhfhhhfdhudfhfhdhdfhfsd
Would become:
hhfhjgglldppprrr
If your input always has exactly two instances of ">" you could use PARSENAME.
declare #SomeValue varchar(100) = 'abs/Supply>hhfhjgglldppprrr>/llllllldsfsjhfhhhfdhudfhfhdhdfhfsd'
select PARSENAME(replace(#SomeValue, '>', '.'), 2)
This will not work correctly if your data also contains any periods (.). We can deal with that if needed with a couple of replace statements. Still very simple and easy to maintain with the same caveat of exactly 2 >.
declare #SomeOtherValue varchar(100) = 'abs/Supply>hhfhjgg.lldppprrr>/llllllldsfsjhfhhhfdhudfhfhdhdfhfsd'
select replace(PARSENAME(replace(replace(#SomeOtherValue, '.', '~!##'), '>', '.'), 2), '~!##', '.')
You can use PATINDEX() to identify the position of the patterns you are looking for (/Supply> and >/) then remove them based on the length of the string:
SELECT LEFT(RIGHT(col,LEN(col) - PATINDEX('%/Supply>%',col) -7), PATINDEX('%>/%', RIGHT(col,LEN(col) - PATINDEX('%Supply>%',col) -7))-1)
Simply replace col in the above with your column name.
Example below with test string abs/Supply>keep>/remove
First remove everything before and including /Supply>:
SELECT RIGHT('abs/Supply>keep>/remove',LEN('abs/Supply>keep>/remove') - PATINDEX('%/Supply>%','abs/Supply>keep>/remove') -7)
This will give keep>/remove
Then remove everything after and including >/:
SELECT LEFT('keep>/remove',PATINDEX('%>/%','keep>/remove') - 1)
This will give keep, the part of the string you want.
Here is the combined version, same as above, just includes the test string instead of col so you can run it easily:
SELECT LEFT(RIGHT('abs/Supply>keep>/remove',LEN('abs/Supply>keep>/remove') - PATINDEX('%/Supply>%','abs/Supply>keep>/remove') -7), PATINDEX('%>/%', RIGHT('abs/Supply>keep>/remove',LEN('abs/Supply>keep>/remove') - PATINDEX('%/Supply>%','abs/Supply>keep>/remove') -7))-1)
This will give keep. You can also replace the string above with the one in your question, I just used a different test string because it is shorter and makes the code more readable.
try this:
DECLARE #inputStr VARCHAR(max)= 'abs/Supply>hhfhjgglldppprrr>/llllllldsfsjhfhhhfdhudfhfhdhdfhfsd'
DECLARE #startString VARCHAR(100)='/Supply>'
DECLARE #EndString VARCHAR(100)='>/'
DECLARE #LenStartString INT = LEN(#startString)
DECLARe #TempInputString VARCHAR(max)='';
DECLARE #StartIndex INT
DECLARE #EndIndex INT
SELECT #StartIndex = CHARINDEX(#startString,#inputStr)+#LenStartString
SELECT #TempInputString = STUFF(#inputStr, 1, #StartIndex, '')
SELECT SUBSTRING(#TempInputString,0,CHARINDEX(#EndString,#TempInputString))
In Single Line
DECLARE #inputStr VARCHAR(max)= 'abs/Supply>hhfhjgglldppprrr>/llllllldsfsjhfhhhfdhudfhfhdhdfhfsd'
DECLARE #startString VARCHAR(100)='/Supply>'
DECLARE #EndString VARCHAR(100)='>/'
SELECT SUBSTRING(STUFF(#inputStr, 1, CHARINDEX(#startString,#inputStr)+LEN(#startString), ''),0,CHARINDEX(#EndString,STUFF(#inputStr, 1,CHARINDEX(#startString,#inputStr)+LEN(#startString), '')))

SQL - Cut string upto a string (first one only)

i have a string like this:
DECLARE #val nvarchar(max)
set #val='id=1 and Name=abc and Address=NY and age=32'
Now i need to cut the string only upto the end of first and.here id length can be 1-100000.So i can fixed a length.
Current situation: id=1 and Name=abc and Address=NY and age=32
Expected result: Name=abc and Address=NY and age=32
Thanks in advance
DECLARE #val NVARCHAR(MAX)
SET #val='id=1 and Name=abc and Address=NY and age=32'
SELECT SUBSTRING(#val, PATINDEX('% and%', #val) + 4, LEN(#val))
SQLFiddle Demo
Other Links
PATINDEX()
LEN()
SUBSTRING()
DECLARE #val nvarchar(max)
DECLARE #val1 int
set #val='id=1 and Name=abc and Address=NY and age=32'
set #val1=CHARINDEX('Name', #val)
select val2=SUBSTRING(#val,#val1,LEN(#val)-(#val1-1))
If I understand correctly what you are after something like this should get you want you want:
substring(#val , CHARINDEX(#val) + 4, len(#val))
I guess we can also do it without a call of LEN and SUBSTRING method.
Something like this would help:
DECLARE #val nvarchar(max)
set #val='id=1 and Name=abc and Address=NY and age=32'
Select #val as OriginalValue
select stuff(#val,1,charindex('d ',#val) + 1,'') as ExpectedResult
We need a call of STUFF method along with CHARINDEX.
Check out how STUFF works.
Remember: STUFF is position oriented (starts with 1).
Here is the output:
use substring function like
#val=substring('#val',9,'remaining char')
see: SUBSTRING(), CHARINDEX(), PATINDEX()
refer here
http://www.sqlinfo.net/sqlserver/sql_server_function_substring.php

Is there any simple way to format decimals in T-SQL?

I know it could be done trivially in a non-SQL environment [post-data processing, frontend, what have you], but that's not possible at the moment. Is there a way to take a decimal(5,2) and convert it to a varchar without the trailing zeroes/decimal points? For example:
declare #number decimal(5,2)
set #number = 123.00
select cast(#number as varchar) as FormattedNumber
And the result is '123.00'. Is there a (simple) way to get '123' instead? And likewise, instead of '123.30', '123.3'? Could do it by figuring out whether or not the hundredths/tenths places were 0 and manually trimming characters, but I wanted to know if there was a more elegant solution.
What about:
SELECT CAST(CAST(#number AS float) AS varchar(10))
However you may want to test this carefully with your raw data first.
This way is pretty simple:
DECLARE #Number DECIMAL(5,2)
SELECT #Number = 123.65
SELECT FormattedNumber = CAST(CAST(#Number AS DECIMAL(3,0)) AS VARCHAR(4))
Returns '124'.
The only thing to consider is whether you want to round up/down, or just strip the zeroes and decimal points without rounding; you'd cast the DECIMAL as an INT in the second case.
For controlled formatting of numbers in T-SQL you should use the FORMAT() function. For example:
DECLARE #number DECIMAL(9,2); SET #number = 1234567.12;
DECLARE #formatted VARCHAR(MAX); SET #formatted = FORMAT(#number, 'N0', 'en-AU');
PRINT #formatted;
The result will be:
1,234,567
The arguments to the FORMAT() function are:
FORMAT(value, format [, culture])
The value argument is your number. The format argument is a CLR type formatting string (in this example, I specified "normal number, zero precision"). The optional culture argument allows you to override the server culture setting to format the number as per a desired culture.
See also the MSDN ref page for FORMAT().
The Convert function may do what you want to do.
ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/a87d0850-c670-4720-9ad5-6f5a22343ea8.htm
Let me try this again....
CREATE FUNCTION saneDecimal(#input decimal(5,2)) returns varchar(10)
AS
BEGIN
DECLARE #output varchar(10)
SET #output = CAST(#input AS varchar(10))
DECLARE #trimmable table (trimval char(1))
INSERT #trimmable VALUES ('0')
INSERT #trimmable VALUES ('.')
WHILE EXISTS (SELECT * FROM #trimmable WHERE trimval = CAST(SUBSTRING(#output, LEN(#output), 1) AS char(1)))
SET #output = LEFT(#output, LEN(#output) - 1)
RETURN #output
END
GO
SELECT dbo.saneDecimal(1.00)
You could strip the trailing zeroes in a while loop:
declare #number decimal(5,2)
declare #str varchar(100)
set #number = 123.00
set #str = #number
while substring(#str,len(#str),1) in ('0','.',',')
set #str = substring(#str,1,len(#str)-1)
But as AdaTheDev commented, this is more easily done client-side.
Simple and elegant? Not so much...but that's T-SQL for you:
DECLARE #number decimal(5,2) = 123.00
DECLARE #formatted varchar(5) = CAST(#number as varchar)
SELECT
LEFT(
#formatted,
LEN(#formatted)
- PATINDEX('%[^0.]%', REVERSE(#formatted))
+ 1
)
Use the Format(value,format string,culture) function in SQL Server 2012+
If you have SQL Server 2012 or Greater you can use the format function like this:
select format(#number,'0') as FormattedNumber
Of course the format function will return an nvarchar, and not a varchar. You can cast to get a specific type.
Also, take a look at the T-SQL STR function in Books Online; this can be used for formatting floats and might work for your case. For some reason it doesn't come up in Google searches relating to this problem.