How to modify data retrieved from select in sql? - sql

suppose i am having some unwanted characters in the data present in a column for eg name column in customers table has data like < ,is there anyway to modify such characters like '<' to blankspace while retrieving this data using select statement? This is to prevent xss scripts showing up due to old data which is having such unwanted characters
e.g:
select *
from customers
returns
Id Name Age city salary
-- ------ --- ---- ------
1 <hari 32 Ahmedabad 4000
2 Khilan 25 Delhi 5678
3 kaushik 23 Kota 234
i want <hari to be displayed as hari when this data is retrieved using select statement.How to achieve this ?

Something like...
SELECT REPLACE(REPLACE(a.name,'<', ''), '>','')
FROM ...

It may be better to write a function to remove special characters. Here the function replaces any character that does not look like a-z,A-Z(if case sensitive),0-9 and Space. You can add more if needed.
For example if you want to retain period(.) the use '[^a-zA-Z0-9 .]'
Function:
CREATE FUNCTION ufn_RemoveSpecialCharacters
(
#String VARCHAR(500),
#Exclude VARCHAR(100),
#CollapseSpaces BIT
)
RETURNS VARCHAR(500)
AS
BEGIN
DECLARE #StartString INT,
#EndString INT,
#FinalString VARCHAR(500),
#CurrentString CHAR(1),
#PreviousString CHAR(1)
SET #StartString = 1
SET #EndString = LEN(ISNULL(#String, ''))
WHILE #StartString <= #EndString
BEGIN
SET #CurrentString = SUBSTRING(#String, #StartString, 1)
SET #PreviousString = SUBSTRING(#String, #StartString-1, 1)
IF #CurrentString LIKE ISNULL(#Exclude,'[^a-zA-Z0-9 ]')
BEGIN
SET #CurrentString = ''
IF #CollapseSpaces = 1
SET #FinalString = CASE WHEN #PreviousString = CHAR(32) THEN ISNULL(#FinalString, '') ELSE ISNULL(#FinalString, '')+' ' END
END
ELSE
BEGIN
SET #FinalString = ISNULL(#FinalString, '') + #CurrentString
IF #CollapseSpaces = 1
BEGIN
SET #FinalString = REPLACE(#FinalString,' ',' ')
END
END
SET #StartString = #StartString + 1
END
--PRINT #String
RETURN LTRIM(RTRIM(#FinalString))
END
GO
Usage:
Does not collapse Spaces
SELECT dbo.ufn_RemoveSpecialCharacters('This #$%string has#$% special #$% characters and spaces))', '[^a-zA-Z0-9 ]', 0)
Collapses multiple Spaces
SELECT dbo.ufn_RemoveSpecialCharacters('This #$%string has#$% special #$% characters and spaces))', '[^a-zA-Z0-9 ]', 1)

Here is the example
SELECT Replace(Column Name, ' ', '') AS C
FROM Contacts
WHERE Replace(Column Name, ' ', '') LIKE 'whatever'
Hope this was helpful

Related

Getting the middle name from a full name field

So, I've got functions to get the first and last names, like so:
create function udf_get_first_name (#string nvarchar(100))
returns nvarchar(50)
as
begin
declare #first_name nvarchar(50)
set #string = ltrim(#string)
set #string = rtrim(#string)
if dbo.udf_get_number_of_spaces(#string) > 0
set #first_name = left(#string, charindex(' ',#string) -1)
else
set #first_name = #string
return #first_name
end
create function udf_get_last_name (#string nvarchar(100))
returns nvarchar(50)
as
begin
set #string = ltrim(#string)
set #string = rtrim(#string)
if dbo.udf_get_number_of_spaces (#string) > 0
begin
set #string = reverse(#string)
set #string = left(#string, charindex(' ', #string) -1)
set #string = reverse(#string)
end
return #string
end
I need to be able to get the middle name, and just can't wrap my head around what I've been reading through my searching so far. Not sure if I'm just being dumb or not.
I also need to be able to sort a name formatted as L/M/F, into the proper columns as well, which I'm having an even harder time with.
Edit: Not all the records have middle names.
You can use the following solution, using a function to get a part of the name or the fullname in a specified format:
--
-- function to get a part of a fullname or to reformat the fullname.
-- #fullname - the fullname to get the part from or to reformat.
-- #format - the format of the output using F (firstname), M (middlename) and L (lastname).
-- the function returns the fullname in specified format or NULL if input is not valid
-- or the part of name is empty.
--
CREATE FUNCTION GetNamePart(#fullname VARCHAR(200), #format VARCHAR(30))
RETURNS VARCHAR(200)
AS
BEGIN
-- replace multiple spaces of the fullname and trim the result.
SET #fullname = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(#fullname, ' ', '<>'), '><', ''), '<>', ' ')))
-- get the different name parts (firstname, middlename and lastname) of the fullname.
DECLARE #first_name VARCHAR(100)
SET #first_name = LTRIM(RTRIM(LEFT(#fullname, CHARINDEX(' ', #fullname))))
DECLARE #last_name VARCHAR(100)
SET #last_name = LTRIM(RTRIM(RIGHT(#fullname, CHARINDEX(' ', REVERSE(#fullname)))))
DECLARE #middle_name VARCHAR(100)
SET #middle_name = LTRIM(RTRIM(SUBSTRING(#fullname, LEN(#first_name) + 1, LEN(#fullname) - LEN(#first_name) - LEN(#last_name))))
-- init the formatted name of the fullname.
DECLARE #formatted_name VARCHAR(100)
-- return only the formatted name if format string is valid.
IF PATINDEX('%[^LMF]%', UPPER(#format)) > 0
SET #formatted_name = ''
ELSE
BEGIN
SET #format = REPLACE(REPLACE(REPLACE(#format, 'M', '##M##'), 'L', '##L##'), 'F', '##F##')
SET #formatted_name = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(UPPER(#format), '##F##', #first_name + ' '), '##M##', #middle_name + ' '), '##L##', #last_name + ' ')))
END
-- check the input (#fullname) for valid value (firstname, lastname or firstname, middlename, lastname).
IF PATINDEX('%_ %_% _%', #fullname) = 0 AND PATINDEX('%_ _%', #fullname) = 0
SET #formatted_name = ''
-- return the new formatted name and replace multiple spaces.
RETURN NULLIF(REPLACE(REPLACE(REPLACE(#formatted_name, ' ', '<>'), '><', ''), '<>', ' '), '')
END
This function GetNamePart is using two parameters (#fullname and #format). The first parameter #fullname is the fullname containing the firstname, lastname and if available the middlename. The second parameter is defining the output format of the name. You can use the letters F (firstname), M (middlename) and L (lastname) to define the format of the output.
So you can use the function GetNamePart to get the middlename of the fullname:
SELECT dbo.GetNamePart(fullname, 'M') FROM table_name
... or to reformat the fullname like this:
SELECT dbo.GetNamePart(fullname, 'LMF') FROM table_name
demo on dbfiddle.uk (demo and test cases)
But you can also use a SELECT query to get the various parts of the name without a function:
SELECT
LTRIM(RTRIM(LEFT(fullname, CHARINDEX(' ', fullname)))) AS first_name,
LTRIM(RTRIM(RIGHT(fullname, CHARINDEX(' ', REVERSE(fullname))))) AS last_name,
LTRIM(RTRIM(CASE WHEN PATINDEX('%_ %_% _%', fullname) > 0 THEN SUBSTRING(fullname, CHARINDEX(' ', fullname) + 1, (CHARINDEX(' ', fullname, CHARINDEX(' ', fullname)+1)-(CHARINDEX(' ', fullname) + 1))) ELSE '' END)) AS middle_name
FROM table_name
demo on dbfiddle.uk
Similar to Sebastian Brosch's answer. I also added the TRIM function after I saw his answer. In this query, it's not necessary. But it's something nice to have. For example, if the user added multiple spaces by mistake, this will remove that.
There might be a better or simpler way to get first, middle and last name. But this is the way I come up with at the moment.
CREATE FUNCTION dbo.SplitFullName(
#FullName NVARCHAR(MAX),
#Format NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #FN NVARCHAR(MAX);
DECLARE #MN NVARCHAR(MAX);
DECLARE #LN NVARCHAR(MAX);
DECLARE #RV NVARCHAR(MAX);
SET #FN = RTRIM(LTRIM(SUBSTRING(#FullName,0, CHARINDEX(' ',#FullName))));
SET #MN = RTRIM(LTRIM(SUBSTRING(#FullName, CHARINDEX(' ',#FullName) + 1 , LEN(#FullName) - (CHARINDEX(' ',#FullName) + CHARINDEX(' ',REVERSE(#FullName)))+1)));
SET #LN = RTRIM(LTRIM(REVERSE(SUBSTRING(REVERSE(#FullName),0, CHARINDEX(' ',REVERSE(#FullName))))));
IF (#Format='FN')
SET #RV = CASE WHEN LEN(#FN) = 0 THEN NULL ELSE #FN END;
ELSE IF (#Format='MN')
SET #RV = CASE WHEN LEN(#MN) = 0 THEN NULL ELSE #MN END;
ELSE IF (#Format='LN')
SET #RV = CASE WHEN LEN(#LN) = 0 THEN NULL ELSE #LN END;;
ELSE
SET #RV = CONCAT(#LN, ' ', CASE WHEN LEN(#MN) = 0 THEN NULL ELSE CONCAT(#MN , ' ') END, #FN);
RETURN #RV;
END;
Example 01
SELECT dbo.SplitFullName('Antonio P. Green', 'FN') AS FN,
dbo.SplitFullName('Antonio P. Green', 'MN') AS MN,
dbo.SplitFullName('Antonio P. Green', 'LN') AS LN,
dbo.SplitFullName('Antonio P. Green', 'LMF') AS LMF;
+---------+----+-------+------------------+
| FN | MN | LN | LMF |
+---------+----+-------+------------------+
| Antonio | P. | Green | Green P. Antonio |
+---------+----+-------+------------------+
Example 02
select dbo.SplitFullName('Cindy Bertha Collier Sproles', 'FN') AS FN,
dbo.SplitFullName('Cindy Bertha Collier Sproles', 'MN') AS MN,
dbo.SplitFullName('Cindy Bertha Collier Sproles', 'LN') AS LN,
dbo.SplitFullName('Cindy Bertha Collier Sproles', 'LMF') AS LMF;
+-------+----------------+---------+------------------------------+
| FN | MN | LN | LMF |
+-------+----------------+---------+------------------------------+
| Cindy | Bertha Collier | Sproles | Sproles Bertha Collier Cindy |
+-------+----------------+---------+------------------------------+
Example 03
SELECT dbo.SplitFullName('Tristan Jackson', 'FN') AS FN,
dbo.SplitFullName('Tristan Jackson', 'MN') AS MN,
dbo.SplitFullName('Tristan Jackson', 'LN') AS LN,
dbo.SplitFullName('Tristan Jackson', 'LMF') AS LMF;
+---------+------+---------+-----------------+
| FN | MN | LN | LMF |
+---------+------+---------+-----------------+
| Tristan | NULL | Jackson | Jackson Tristan |
+---------+------+---------+-----------------+
You can handle this using Multiple comma separated CTE.
declare #str nvarchar(max) ='kareena kapoor khan';
with
t0 AS (select charindex(' ',#str) pos, #str name ),
t1 AS (select charindex(' ',#str,pos+1)pos,#str name from t0)
select substring(t0.name,0,t0.pos) "firstName",
substring(t0.name,t0.pos+1,(t1.pos-t0.pos)) "MiddleName",
substring(t0.name,t1.pos+1,(len(t0.name)- t1.pos)) "Lastname"
from t0
inner join t1 on t0. name= t1.name
output
|firstName | MiddleName |Lastname
|kareena | kapoor |khan
Also, Instead of creating 3 function for first name , middle name and last name you can just create a single function and pass parameter as #namepart.
The future is start as sql-server 2016:
use STRING_SPLIT function
Use Northwind
Go
SELECT ProductID, value
FROM Products
CROSS APPLY STRING_SPLIT(ProductName, ' ');
by this query you can split names... then use by Row() function you can choose middle name.
STRING_SPLIT requires the compatibility level to be at least 130. When the level is less than 130, SQL Server is unable to find the STRING_SPLIT function.
Select Ltrim(SUBSTRING(name,CharIndex(' ',name),
CAse When (CHARINDEX(' ',name,CHARINDEX(' ',name)+1)-CHARINDEX(' ',name))<=0 then 0
else CHARINDEX(' ',name,CHARINDEX(' ',name)+1)-CHARINDEX(' ',name) end )) as MiddleName
From TableName

strip leading zeroes in sql in string after space

I have a contact number field which stores number as
countrycode + ' ' + phonenumber..
Now i want to strip leading zeroes from phone number
I tried using
UPDATE [dbo].[User]
SET PhoneNumber = REPLACE(LTRIM(REPLACE([PhoneNumber], '0', ' ')), ' ', '0')
but this replaces the space in between with '0'
Any suggestions?
Try converting the value to int or numeric
Eg:
select '91 004563' as Input, CONVERT(INT, SUBSTRING('91 004563',CHARINDEX(' ','91 004563')+1,100)) as Output
This gives the result
Input Output
--------- ------
91 004563 4563
Try this: SUBSTRING(PhoneNumber, PATINDEX('%[^0 ]%', PhoneNumber + ' '), LEN(PhoneNumber))
Try:
declare #PhoneNumber varchar(max) = '00000000000000000000001200000031'
while substring(#PhoneNumber,1,1)='0'
begin
set #PhoneNumber = SUBSTRING(#PhoneNumber,2,LEN(#PhoneNumber))
end
select #PhoneNumber
Addressing your comment:
declare #PhoneNumber varchar(max) = '91 00000000000000000000001200000031'
declare #tempphn varchar(max) = substring(#PhoneNumber,4,len(#PhoneNumber) )
while substring(#tempphn,1,1)='0'
begin
set #tempphn = SUBSTRING(#tempphn,2,LEN(#tempphn))
end
select #tempphn

SQL Select Value From Comma Delimited List

I have a field in my database called "Notes". It contains a comma delimited list of values.
I want to perform a SELECT Query that only returns the first value in the "Notes" field.
This query would also return additional fields from the database.
for example
SELECT Name, Phone, Notes (only the first value)
FROM Table1
Is this possible, and how do I do it?
You can use CHARINDEX with SUBSTRING:
SELECT Name, Phone, SUBSTRING(Notes, 1, CHARINDEX(',', Notes)) AS first_value
FROM Table1
Demo
DECLARE #csv varchar(50)
SET #csv = 'comma after this, and another,'
SELECT SUBSTRING(#csv, 1, CHARINDEX(',', #csv)) AS first_value
Result
| first_value |
--------------------
| comma after this |
As mentioned in the comments, you should normalize your structure and not have more than one value stored in a single attribute.
SELECT Name, Phone, Left(Notes, CharIndex(',', Notes + ',')) FirstNote
FROM Table1
You need the Notes + ',' bit in the CharIndex to work correctly - see this example (I have included njk's answer)
with Table1(Name, Phone, Notes) as (
select 'abc', '123', 'Some,notes,here' union all
select 'abd', '124', 'Single-note' union all
select 'abe', '125', '' union all
select 'syz', '126', null
)
---
SELECT Name, Phone, Left(Notes, CharIndex(',', Notes + ',')-1) FirstNote
,SUBSTRING(Notes, 0, CHARINDEX(',', Notes)) AS njk
FROM Table1
Results
Name Phone FirstNote njk
---- ----- --------------- ---------------
abc 123 Some Some
abd 124 Single-note
abe 125
syz 126 NULL NULL
SELECT name,
phones,
split_part(notes, ',', 1) as first_notes
FROM Table1
solutions for Select Value From Comma Delimited List
I was looking for a more general answer (not just the first field but an arbitrarily specified one) so I modified Kermit's answer and put it in a function. Here it is in case it helps save somebody else time
CREATE FUNCTION [dbo].[fnGetFieldXFromDelimitedList] (#SearchIn nvarchar(max)
, #Delimiter char(1), #FieldNum int ) RETURNS nvarchar(max) as BEGIN
/*
fnGetFieldXFromDelimitedList(#SearchIn, #Delimiter, #FieldNum)
Returns the Nth value (specified by #FieldNum, first is 1 not 0)
from #SearchIn assuming #SearchIn is a list of multiple values
delimited by #Delimiter
DECLARE #SearchIn nvarchar(max) = 'F1, Field 2, F3,, F5, F6, F7'
DECLARE #Delimiter char(1) = ','
DECLARE #FieldNum int = 7
--*/
--SELECT dbo.fnGetFieldXFromDelimitedList ('F1, Field 2, F3,, F5, F6, F7', ',', 5)
DECLARE #PosStart int = 1 --SUBSTRING(SearchIn, StartPos, StrLen) considers 1 the first character
DECLARE #PosEnd INT = LEN(#SearchIn)
DECLARE #TempString nvarchar(max) = CONCAT(#SearchIn, #Delimiter)
DECLARE #TempNum INT = 1
DECLARE #RetVal nvarchar(max) = ''
--SElECT SUBSTRING(#SearchIn, 1, 1)
SET #PosEnd = CHARINDEX(#Delimiter, #TempString, #PosStart + LEN(#Delimiter))
WHILE #TempNum < #FieldNum AND #PosStart > 0 AND #PosStart < LEN(#TempString) BEGIN
SET #PosStart = CHARINDEX(#Delimiter, #TempString, #PosStart) + LEN(#Delimiter)
SET #PosEnd = CHARINDEX(#Delimiter, #TempString, #PosStart)
SET #TempNum = #TempNum + 1
--SELECT #PosStart, #PosEnd , #TempNum
END --WHILE
IF #TempNum = #FieldNum AND #PosEnd > 0 BEGIN
SET #RetVal = SUBSTRING(#TempString, #PosStart, #PosEnd - #PosStart)
END ELSE BEGIN
SET #RetVal = NULL
END
--SELECT #RetVal
RETURN #RetVal
END

SQL: problem word count with len()

I am trying to count words of text that is written in a column of table. Therefor I am using the following query.
SELECT LEN(ExtractedText) -
LEN(REPLACE(ExtractedText, ' ', '')) + 1 from EDDSDBO.Document where ID='100'.
I receive a wrong result that is much to high.
On the other hand, if I copy the text directly into the statement then it works, i.e.
SELECT LEN('blablabla text') - LEN(REPLACE('blablabla text', ' ', '')) + 1.
Now the datatype is nvarchar(max) since the text is very long. I have already tried to convert the column into text or ntext and to apply datalength() instead of len(). Nevertheless I obtain the same result that it does work as a string but does not work from a table.
You're counting spaces not words. That will typically yield an approximate answer.
e.g.
' this string will give an incorrect result '
Try this approach: http://www.sql-server-helper.com/functions/count-words.aspx
CREATE FUNCTION [dbo].[WordCount] ( #InputString VARCHAR(4000) )
RETURNS INT
AS
BEGIN
DECLARE #Index INT
DECLARE #Char CHAR(1)
DECLARE #PrevChar CHAR(1)
DECLARE #WordCount INT
SET #Index = 1
SET #WordCount = 0
WHILE #Index <= LEN(#InputString)
BEGIN
SET #Char = SUBSTRING(#InputString, #Index, 1)
SET #PrevChar = CASE WHEN #Index = 1 THEN ' '
ELSE SUBSTRING(#InputString, #Index - 1, 1)
END
IF #PrevChar = ' ' AND #Char != ' '
SET #WordCount = #WordCount + 1
SET #Index = #Index + 1
END
RETURN #WordCount
END
GO
usage
DECLARE #String VARCHAR(4000)
SET #String = 'Health Insurance is an insurance against expenses incurred through illness of the insured.'
SELECT [dbo].[WordCount] ( #String )
Leading spaces, trailing spaces, two or more spaces between the neighbouring words – these are the likely causes of the wrong results you are getting.
The functions LTRIM() and RTRIM() can help you eliminate the first two issues. As for the third one, you can use REPLACE(ExtractedText, ' ', ' ') to replace double spaces with single ones, but I'm not sure if you do not have triple ones (in which case you'd need to repeat the replacing).
UPDATE
Here's a UDF that uses CTEs and ranking to eliminate extra spaces and then counts the remaining ones to return the quantity as the number of words:
CREATE FUNCTION fnCountWords (#Str varchar(max))
RETURNS int
AS BEGIN
DECLARE #xml xml, #res int;
SET #Str = RTRIM(LTRIM(#Str));
WITH split AS (
SELECT
idx = number,
chr = SUBSTRING(#Str, number, 1)
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND LEN(#Str)
),
ranked AS (
SELECT
idx,
chr,
rnk = idx - ROW_NUMBER() OVER (PARTITION BY chr ORDER BY idx)
FROM split
)
SELECT #res = COUNT(DISTINCT rnk) + 1
FROM ranked
WHERE chr = ' ';
RETURN #res;
END
With this function your query will be simply like this:
SELECT fnCountWords(ExtractedText)
FROM EDDSDBO.Document
WHERE ID='100'
UPDATE 2
The function uses one of the system tables, master..spt_values, as a tally table. The particular subset used contains only values from 0 to 2047. This means the function will not work correctly for inputs longer than 2047 characters (after trimming both leading and trailing spaces), as #t-clausen.dk has correctly noted in his comment. Therefore, a custom tally table should be used if longer input strings are possible.
Replace the spaces with something that never occur in your text like ' $!' or pick another value.
then replace all '$! ' and '$!' with nothing this way you never have more than 1 space after a word. Then use your current script. I have defined a word as a space followed by a non-space.
This is an example
DECLARE #T TABLE(COL1 NVARCHAR(2000), ID INT)
INSERT #T VALUES('A B C D', 100)
SELECT LEN(C) - LEN(REPLACE(C,' ', '')) COUNT FROM (
SELECT REPLACE(REPLACE(REPLACE(' ' + COL1, ' ', ' $!'), '$! ',''), '$!', '') C
FROM #T ) A
Here is a recursive solution
DECLARE #T TABLE(COL1 NVARCHAR(2000), ID INT)
INSERT #T VALUES('A B C D', 100)
INSERT #T VALUES('have a nice day with 7 words', 100)
;WITH CTE AS
(
SELECT 1 words, col1 c, col1 FROM #t WHERE id = 100
UNION ALL
SELECT words +1, right(c, len(c) - patindex('% [^ ]%', c)), col1 FROM cte
WHERE patindex('% [^ ]%', c) > 0
)
SELECT words, col1 FROM cte WHERE patindex('% [^ ]%', c) = 0
You should declare the column using the varchar data type, like:
create table emp(ename varchar(22));
insert into emp values('amit');
select ename,len(ename) from emp;
output : 4

SQL method to replace repeating blanks with single blanks

Is there a more elegant way of doing this. I want to replace repeating blanks with single blanks....
declare #i int
set #i=0
while #i <= 20
begin
update myTable
set myTextColumn = replace(myTextColumn, ' ', ' ')
set #i=#i+1
end
(its sql server 2000 - but I would prefer generic SQL)
This works:
UPDATE myTable
SET myTextColumn =
REPLACE(
REPLACE(
REPLACE(myTextColumn
,' ',' '+CHAR(1)) -- CHAR(1) is unlikely to appear
,CHAR(1)+' ','')
,CHAR(1),'')
WHERE myTextColumn LIKE '% %'
Entirely set-based; no loops.
So we replace any two spaces with an unusual character and a space. If we call the unusual character X, 5 spaces become: ' X X ' and 6 spaces become ' X X X'. Then we replace 'X ' with the empty string. So 5 spaces become ' ' and 6 spaces become ' X'. Then, in case there was an even number of spaces, we remove any remaining 'X's, leaving a single space.
Here is a simple set based way that will collapse multiple spaces into a single space by applying three replaces.
DECLARE #myTable TABLE (myTextColumn VARCHAR(50))
INSERT INTO #myTable VALUES ('0Space')
INSERT INTO #myTable VALUES (' 1 Spaces 1 Spaces. ')
INSERT INTO #myTable VALUES (' 2 Spaces 2 Spaces. ')
INSERT INTO #myTable VALUES (' 3 Spaces 3 Spaces. ')
INSERT INTO #myTable VALUES (' 4 Spaces 4 Spaces. ')
INSERT INTO #myTable VALUES (' 5 Spaces 5 Spaces. ')
INSERT INTO #myTable VALUES (' 6 Spaces 6 Spaces. ')
select replace(
replace(
replace(
LTrim(RTrim(myTextColumn)), ---Trim the field
' ',' |'), ---Mark double spaces
'| ',''), ---Delete double spaces offset by 1
'|','') ---Tidy up
AS SingleSpaceTextColumn
from #myTable
Your Update statement can now be set based:
update #myTable
set myTextColumn = replace(
replace(
replace(
LTrim(RTrim(myTextColumn)),
' ',' |'),
'| ',''),
'|','')
Use an appropriate Where clause to limit the Update to only the rows that have you need to update or maybe have double spaces.
Example:
where 1<=Patindex('% %', myTextColumn)
I have found an external write up on this method: REPLACE Multiple Spaces with One
select
string = replace(
replace(
replace(' select single spaces',' ','<>')
,'><','')
,'<>',' ')
Replace duplicate spaces with a single space in T-SQL
SELECT 'starting...' --sets ##rowcount
WHILE ##rowcount <> 0
update myTable
set myTextColumn = replace(myTextColumn, ' ', ' ')
where myTextColumn like '% %'
Not very SET Based but a simple WHILE would do the trick.
CREATE TABLE #myTable (myTextColumn VARCHAR(32))
INSERT INTO #myTable VALUES ('NoSpace')
INSERT INTO #myTable VALUES ('One Space')
INSERT INTO #myTable VALUES ('Two Spaces')
INSERT INTO #myTable VALUES ('Multiple Spaces .')
WHILE EXISTS (SELECT * FROM #myTable WHERE myTextColumn LIKE '% %')
UPDATE #myTable
SET myTextColumn = REPLACE(myTextColumn, ' ', ' ')
WHERE myTextColumn LIKE '% %'
SELECT * FROM #myTable
DROP TABLE #myTable
Step through the characters one by one, and maintain a record of the previous character. If the current character is a space, and the last character is a space, stuff it.
CREATE FUNCTION [dbo].[fnRemoveExtraSpaces] (#Number AS varchar(1000))
Returns Varchar(1000)
As
Begin
Declare #n int -- Length of counter
Declare #old char(1)
Set #n = 1
--Begin Loop of field value
While #n <=Len (#Number)
BEGIN
If Substring(#Number, #n, 1) = ' ' AND #old = ' '
BEGIN
Select #Number = Stuff( #Number , #n , 1 , '' )
END
Else
BEGIN
SET #old = Substring(#Number, #n, 1)
Set #n = #n + 1
END
END
Return #number
END
GO
select [dbo].[fnRemoveExtraSpaces]('xxx xxx xxx xxx')
Here is a Simplest solution :)
update myTable
set myTextColumn = replace(replace(replace(LTrim(RTrim(myTextColumn )),' ','<>'),'><',''),'<>',' ')
create table blank(
field_blank char(100))
insert into blank values('yyy yyyy')
insert into blank values('xxxx xxxx')
insert into blank values ('xxx xxx')
insert into blank values ('zzzzzz zzzzz')
update blank
set field_blank = substring(field_blank,1,charindex(' ',field_blank)-1) + ' ' + ltrim(substring(field_blank,charindex(' ',field_blank) + 1,len(field_blank)))
where CHARINDEX (' ' , rtrim(field_blank)) > 1
select * from blank
For me the above examples almost did a trick but I needed something that was more stable and independent of the table or column or a set number of iterations. So this is my modification from most of the above queries.
CREATE FUNCTION udfReplaceAll
(
#OriginalText NVARCHAR(MAX),
#OldText NVARCHAR(MAX),
#NewText NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
WHILE (#OriginalText LIKE '%' + #OldText + '%')
BEGIN
SET #OriginalText = REPLACE(#OriginalText,#OldText,#NewText)
END
RETURN #OriginalText
END
GO
Lets say, your Data like this
Table name : userdata Field: id, comment, status,
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
id, "I love -- -- - -spaces -- - my INDIA" , "Active" <br>
So just do like this
update userdata set comment=REPLACE(REPLACE(comment," ","-SPACEHERE-"),"-SPACEHERE"," ");
I didn't tested , but i think this will work.
Try this:
UPDATE Ships
SET name = REPLACE(REPLACE(REPLACE(name, ' ', ' ' + CHAR(1)), CHAR(1) + ' ', ''), CHAR(1), '')
WHERE name LIKE '% %'
REPLACE(REPLACE(REPLACE(myTextColumn,' ',' %'),'% ',''),'%','')
Statement above worked terrifically for replacing multiple spaces with a single space. Optionally add LTRIM and RTRIM to remove spaces at the beginning.
Got it from here: http://burnignorance.com/database-tips-and-tricks/remove-multiple-spaces-from-a-string-using-sql-server/
WHILE
(SELECT count(myIDcolumn)
from myTable where myTextColumn like '% %') > 0
BEGIN
UPDATE myTable
SET myTextColumn = REPLACE(myTextColumn ,' ',' ')
END
Try it:
CREATE OR REPLACE FUNCTION REM_SPACES (TEXTO VARCHAR(2000))
RETURNS VARCHAR(2000)
LANGUAGE SQL
READS SQL DATA
BEGIN
SET TEXTO = UPPER(LTRIM(RTRIM(TEXTO)));
WHILE LOCATE(' ',TEXTO,1) >= 1 DO
SET TEXTO = REPLACE(TEXTO,' ',' ');
END WHILE;
RETURN TEXTO;
END
Update myTable set myTextColumn = replace(myTextColumn, ' ', ' ');
The above query will remove all the double blank spaces with single blank space
But this would work only once.