Given the following variable:
declare #str nvarchar(50) = 'abc'
between 'a' and 'b' there is a hidden character which is: nchar(8207)
therefore:
select len(#str) --4
and:
select unicode(SUBSTRING(#str,2,1)) --8207
my problem is that I have many such records, and I have to find all these characters and delete them.
I'm trying find by CHARINDEX or REPLACE but it just does not recognize this character:
select CHARINDEX(Nchar(unicode(8207)),#str) --0
select REPLACE (#str , Nchar(unicode(8207)), '1') --abc
It seems that REPLACE() does indeed not work.
Looks like you will need to use STUFF()
DECLARE #Moo NVARCHAR(50) = CONCAT('a', NCHAR(8207), 'b', 'c')
SELECT #Moo
,LEN(#Moo)
,LEN(STUFF(#moo, 2, 1, ''))
,STUFF(#moo, 2, 1, '')
However, this leaves you with having to know the locations of the offending unprintable characters. A WHILE loop or Tally table might serve you well here.
I have a a col that is a text field (i know not used any more) that i need to compare. (the instruction field is a text field)
Case when rtrim(cast(RT.INSTRUCTIONS as varchar(max))) = rtrim(cast(HQ.INSTRUCTIONS as varchar(max))) then 'TRUE' Else 'FALSE' end as INSTRUCTIONS.
the value in RT.Instructions is "Check the oil levels every 30 hours. "
the value in HQ.Instructions is "Check the oil levels every 30 hours."
Why wont the trailing blank go away. i did a len on both and hq is 1 less then the rt value.
I also am having the same issue on a varchar(60) field.
Perhaps there is a character that isn't being picked up. Maybe the following will be useful in finding that value. Or maybe just get you started down the right path.
DECLARE #Char INT = 0
DECLARE #Tab TABLE (Id INT, Chr VARCHAR(5), Instructions VARCHAR(MAX), c VARCHAR(MAX))
WHILE #Char < = 256
BEGIN
INSERT INTO #Tab
SELECT Id
,CONVERT(NVARCHAR,CHAR(#Char)) Chr
,CONVERT(NVARCHAR,RIGHT(RTRIM(rt.Instructions),1)) InstructionChar
,CONVERT(NVARCHAR,CHAR(CONVERT(int,#Char))) c
FROM YourTable
WHERE RIGHT(RTRIM(Instructions),1) LIKE '%'+CHAR(CONVERT(int,#Char))
AND RIGHT(RTRIM(Instructions),1) NOT LIKE '[A-Za-z]'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE '[0-9]'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE '.'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE ']'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE ')'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE '"'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE '}'
AND RIGHT(RTRIM(Instructions),1) NOT LIKE '/'
SET #Char = #Char + 1
END
SELECT DISTINCT *
FROM #Tab
Sorry : I'm not allowed to write comments yet
First try :
Case when left(rtrim(cast(RT.INSTRUCTIONS as varchar(max))),len(HQ.INSTRUCTIONS)) = rtrim(cast(HQ.INSTRUCTIONS as varchar(max))) then 'TRUE' Else 'FALSE' end as INSTRUCTIONS
To check if no other issue is concerned.
Then do :
SELECT ASCII(right(RT.INSTRUCTIONS,1))
To confirm that the trailling space is a "real" space : this query should display 32.
CHAR(32) => ' '
ASCII (' ') => 32
I bet you will get 16O. 160 means the last caracter is an non-breaking space witch is not concerned by trim functions...
If so, you will have to build a scalar function like :
ALTER FUNCTION [dbo].[fn_Replace_NonBreakingSpace]
(
#InputString varchar(max),
)
RETURNS varchar(MAX)
AS
BEGIN
RETURN REPLACE(#InputString, char(160), char(32))
END
And then :
Case when rtrim(dbo.fn_Replace_NonBreakingSpace(RT.INSTRUCTIONS)) = rtrim(dbo.fn_Replace_NonBreakingSpace(HQ.INSTRUCTIONS)) then 'TRUE' Else 'FALSE' end as INSTRUCTIONS
I am trying to write a stored procedure in sql server 2008,I need to remove unwanted spaces in the entries of my table.I categorized the entries in my table to 3 types.My store procedure should remove the spaces around single letter,like,
A G M words to AGM words
words A G M words to words AGM words
A G words to AG words
I tried following stored procedure.
CREATE proc At1 #name nvarchar(100)
as
declare #start int
declare #temp1 nvarchar(100)
declare #temp nvarchar(100)
declare #NthPosition int
declare #N int
set #N=LEN(#name)
set #start=1
set #temp1=''
set #temp=''
set #NthPosition=charindex(' ',#name,#start)
if(#NthPosition<>0)
begin
while (#NthPosition<>0 and #N<>0)
begin
set #temp1=SUBSTRING(#name,#start,#NthPosition-1)
if(#temp<>'')
begin
if(len(#temp1)=1)
begin
set #temp=(#temp+#temp1)
end
else
begin
set #temp=(#temp+' '+#temp1)
end
end
else
begin
set #temp=#temp1
end
set #start=#NthPosition+1
set #N=#N-#NthPosition
set #NthPosition=0
set #NthPosition=CHARINDEX(' ',#name,#start)
end
end
else
begin
select #name
end
select #temp
GO
and i used ,
exec At1 'apple A G M mango'
My expected result: apple AGM mango
But my actual result:apple
I am unable to figure out where the error is..Any suggestions in this regard is more helpful.
I tried to use computed column that would clear the space and i was able to find solution only for pattern #3.I am unable to frame a computed column definition suitable for all the 3 patterns..... Please share your thoughts that will be helpful to me
I think this covers all the cases:
CREATE proc At1 #Name nvarchar(100)
as
declare #New nvarchar(100)
declare #SpacePos int
declare #Single bit
select #New = '',#Single = 0
select #Name = LTRIM(#Name)
while LEN(#name) > 0
begin
set #SpacePos = CHARINDEX(' ',#Name)
if #SpacePos = 0 --No more spaces in the string
begin
select #New = #New + CASE WHEN #Single = 1 and LEN(#Name) > 1 THEN ' ' ELSE '' END + #Name,
#Name = ''
end
else if #SpacePos = 2 --Single character "word"
begin
select #New = #New + SUBSTRING(#Name,1,1),
#Name = SUBSTRING(#Name,3,100),
#Single = 1
end
else --Multi-character word
begin
select #New = #New + CASE WHEN #Single = 1 THEN ' ' ELSE '' END + SUBSTRING(#Name,1,#SpacePos),
#Name = SUBSTRING(#Name,#SpacePos+1,100),
#Single = 0
end
end
select #New
go
And the examples:
exec At1 'apple A G M mango'
exec At1 'A G M words'
exec At1 'words A G M'
Produces:
apple AGM mango
AGM words
words AGM
(As a simplifying assumption, I assumed I was okay to remove any leading spaces from the original string. I also assume there are no double spaces in the string. If neither of those assumptions is accurate, a bit more work is required)
There might be a little more simpler approach to this, use replace instead of looping through everything and use the substring method.
But then again, you also might look at your input. How does this "processor" knows what a word is? For a matter of fact, the word applea (apple a) might not be a word you are looking for, where this processor potentially will see it as a word (theoretical)
The best thing you can do is to separate your input, for example with an semicolon ";". Then you can use a split functionallity to make those values into a table (for example look at this post : T-SQL: split and aggregate comma-separated values). Next you can use the replace function on it.
You get something like this
select replace(s.value, ' ' , ''), * from split(#value) as s
What would be the best solution, if i have a table like this:
Value Formular
12 'SELECT Value+5 AS result'
15 'SELECT 4/Value+3 AS result'
16 'SELECT 5 AS result'
So, there are SQL-Statemants (as nvarchar(max)) in the Formular-Column. Now i need to calc for each row the result.
Current approach is a WHILE with cursor and handle each row for itself.
We need to use a temp-table for each row, because we were unable to find a better solution, how to get the result from the exec. Like:
declare #Value decimal(18,4);
create table #t(val decimal(18,4))
insert into #t exec(#formular)
select val from #t
We have >100'000 such rows, and this takes about ~2h do compute. (The formulas and values of course complexer, than in the example given)
Is there any possibility to get something like
SELECT Value, exec(Formular) as result FROM calctable
Thanks
EDIT:
Okay, sofar I found atleast a workaround for the EXEC() and temptable:
declare #formular as nvarchar(max)
declare #r_value decimal(18,4);
set #formular='....'
set #formular='select #r_value = Value FROM (' + #formular + ')dt'
EXEC sp_executesql #formular, N'#r_value DECIMAL(18,4) OUTPUT', #r_value OUTPUT
UPDATE Result_Values SET [Value]=#r_value WHERE ID=#calc_id;
This example can be executed:
Creating a table like your calctable, you can omit this part.
create table calctable(value int)
insert calctable values(1)
insert calctable values(3)
Populating a temp table, you can replace this with your own table.
declare #t table(value int, Formular varchar(50))
insert #t values(12,'Value+5 AS result' )
insert #t values(15,'4/Value+3 AS result')
insert #t values(16,'5 AS result')
This is the syntax you need:
declare #sql varchar(max)
select #sql = coalesce(#sql +' union all ', '') + 'select ' + cast(value as varchar(16)) +' value,'+formular+' from calctable' from #t
exec (#sql)
Result:
value result
12 6
12 8
15 7
15 4
16 5
16 5
I would like to replace (or remove) a newline character in a TSQL-string.
Any Ideas?
The obvious
REPLACE(#string, CHAR(13), '')
just won't do it...
Actually a new line in a SQL command or script string can be any of CR, LF or CR+LF. To get them all, you need something like this:
SELECT REPLACE(REPLACE(#str, CHAR(13), ''), CHAR(10), '')
REPLACE(#string, CHAR(13) + CHAR(10), '')
I may be a year late to the party, but I work on queries & MS-SQL every day, and I got tired of the built-in functions LTRIM() & RTRIM() (and always having to call them together), and of not catching 'dirty' data that had newlines at the end, so I decided it was high time to implement a better TRIM function. I'd welcome peer feedback!
Disclaimer: this actually removes (replaces with a single whitespace) extended forms of whitespace (tab, line-feed, carriage-return, etc.), so it's been renamed as "CleanAndTrim" from my original answer. The idea here is that your string doesn't need such extra special-whitespace characters inside it, and so if they don't occur at the head/tail, they should be replaced with a plain space. If you purposefully stored such characters in your string (say, your column of data that you're about to run this on), DON'T DO IT! Improve this function or write your own that literally just removes those characters from the endpoints of the string, not from the 'body'.
Okay, now that the disclaimer is updated, here's the code.
-- =============================================
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab,
-- form-feed, & carriage-return (respectively), with a whitespace
-- (and then trims that off if it's still at the beginning or end, of course).
-- =============================================
CREATE FUNCTION [fn_CleanAndTrim] (
#Str nvarchar(max)
)
RETURNS nvarchar(max) AS
BEGIN
DECLARE #Result nvarchar(max)
SET #Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
LTRIM(RTRIM(#Str)), CHAR(9), ' '), CHAR(10), ' '), CHAR(11), ' '), CHAR(12), ' '), CHAR(13), ' ')))
RETURN #Result
END
Cheers!
Another Disclaimer:
Your typical Windows line-break is CR+LF, so if your string contains those, you'd end up replacing them with "double" spaces.
UPDATE, 2016:
A new version that gives you the option to replace those special-whitespace characters with other characters of your choice! This also includes commentary and the work-around for the Windows CR+LF pairing, i.e. replaces that specific char-pair with a single substitution.
IF OBJECT_ID('dbo.fn_CleanAndTrim') IS NULL
EXEC ('CREATE FUNCTION dbo.fn_CleanAndTrim () RETURNS INT AS BEGIN RETURN 0 END')
GO
-- =============================================
-- Author: Nate Johnson
-- Source: http://stackoverflow.com/posts/24068265
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab, form-feed,
-- & carriage-return (respectively), with a whitespace or specified character(s).
-- Option "#PurgeReplaceCharsAtEnds" determines whether or not to remove extra head/tail
-- replacement-chars from the string after doing the initial replacements.
-- This is only truly useful if you're replacing the special-chars with something
-- **OTHER** than a space, because plain LTRIM/RTRIM will have already removed those.
-- =============================================
ALTER FUNCTION dbo.[fn_CleanAndTrim] (
#Str NVARCHAR(MAX)
, #ReplaceTabWith NVARCHAR(5) = ' '
, #ReplaceNewlineWith NVARCHAR(5) = ' '
, #PurgeReplaceCharsAtEnds BIT = 1
)
RETURNS NVARCHAR(MAX) AS
BEGIN
DECLARE #Result NVARCHAR(MAX)
--The main work (trim & initial replacements)
SET #Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
LTRIM(RTRIM(#Str)) --Basic trim
, NCHAR(9), #ReplaceTabWith), NCHAR(11), #ReplaceTabWith) --Replace tab & vertical-tab
, (NCHAR(13) + NCHAR(10)), #ReplaceNewlineWith) --Replace "Windows" linebreak (CR+LF)
, NCHAR(10), #ReplaceNewlineWith), NCHAR(12), #ReplaceNewlineWith), NCHAR(13), #ReplaceNewlineWith))) --Replace other newlines
--If asked to trim replacement-char's from the ends & they're not both whitespaces
IF (#PurgeReplaceCharsAtEnds = 1 AND NOT (#ReplaceTabWith = N' ' AND #ReplaceNewlineWith = N' '))
BEGIN
--Purge from head of string (beginning)
WHILE (LEFT(#Result, DATALENGTH(#ReplaceTabWith)/2) = #ReplaceTabWith)
SET #Result = SUBSTRING(#Result, DATALENGTH(#ReplaceTabWith)/2 + 1, DATALENGTH(#Result)/2)
WHILE (LEFT(#Result, DATALENGTH(#ReplaceNewlineWith)/2) = #ReplaceNewlineWith)
SET #Result = SUBSTRING(#Result, DATALENGTH(#ReplaceNewlineWith)/2 + 1, DATALENGTH(#Result)/2)
--Purge from tail of string (end)
WHILE (RIGHT(#Result, DATALENGTH(#ReplaceTabWith)/2) = #ReplaceTabWith)
SET #Result = SUBSTRING(#Result, 1, DATALENGTH(#Result)/2 - DATALENGTH(#ReplaceTabWith)/2)
WHILE (RIGHT(#Result, DATALENGTH(#ReplaceNewlineWith)/2) = #ReplaceNewlineWith)
SET #Result = SUBSTRING(#Result, 1, DATALENGTH(#Result)/2 - DATALENGTH(#ReplaceNewlineWith)/2)
END
RETURN #Result
END
GO
The Newline in T-SQL is represented by CHAR(13) & CHAR(10) (Carriage return + Line Feed). Accordingly, you can create a REPLACE statement with the text you want to replace the newline with.
REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')
To do what most people would want, create a placeholder that isn't an actual line breaking character. Then you can actually combine the approaches for:
REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')
This way you replace only once. The approach of:
REPLACE(REPLACE(MyField, CHAR(13), ''), CHAR(10), '')
Works great if you just want to get rid of the CRLF characters, but if you want a placeholder, such as
<br/>
or something, then the first approach is a little more accurate.
In SQL Server 2017 & later, use Trim
Select Trim(char(10) + char(13) from #str)
it trims on starting and ending, not in the middle
the order of \r and \n does not matter
I use it to trim special characters for a file name
Select Trim(char(10) + char(13) + ' *<>' from #fileName)
If your column data type is 'text' then you will get an error message as
Msg 8116, Level 16, State 1, Line 2 Argument data type text is
invalid for argument 1 of replace function.
In this case you need to cast the text as nvarchar and then replace
SELECT REPLACE(REPLACE(cast(#str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
Sometimes
REPLACE(myString, CHAR(13) + CHAR(10), ' ')
won't work. In that case use the following snippet code:
REPLACE(REPLACE(myString, CHAR(13),''), CHAR(10), ' ')
If you have an issue where you only want to remove trailing characters, you can try this:
WHILE EXISTS
(SELECT * FROM #ReportSet WHERE
ASCII(right(addr_3,1)) = 10
OR ASCII(right(addr_3,1)) = 13
OR ASCII(right(addr_3,1)) = 32)
BEGIN
UPDATE #ReportSet
SET addr_3 = LEFT(addr_3,LEN(addr_3)-1)
WHERE
ASCII(right(addr_3,1)) = 10
OR ASCII(right(addr_3,1)) = 13
OR ASCII(right(addr_3,1)) = 32
END
This solved a problem I had with addresses where a procedure created a field with a fixed number of lines, even if those lines were empty. To save space in my SSRS report, I cut them down.
If you have have open procedure with using sp_helptext then just copy all text in new sql query and press ctrl+h button use regular expression to replace and put ^\n in find field replace with blank .
for more detail check image.enter image description here
To #Cerebrus solution: for H2 for strings "+" is not supported. So:
REPLACE(string, CHAR(13) || CHAR(10), 'replacementString')
I was wanting to sanitize the contents of a column to generate a csv file, so want to get rid of the comma (,) within the varchar as well as newline and carrage-return.
I also wanted to eventually use the generated csv to create another script (to insert rows into another db) so also needed to change ' within the varchar to '' so ended up with this...
REPLACE(REPLACE(REPLACE(REPLACE(ErrorMessage, CHAR(13), ''), CHAR(10), ''),',',''),'''','''''')
There may be other nicer ways but it got the job done.
The answer posted above/earlier that was reported to replace CHAR(13)CHAR(10) carriage return:
REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')
Will never get to the REPLACE(MyField, CHAR(13) + CHAR(10), 'something else') portion of the code and will return the unwanted result of:
'something else''something else'
And NOT the desired result of a single:
'something else'
That would require the REPLACE script to be rewritten as such:
REPLACE(REPLACE(REPLACE(MyField, CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(13) + CHAR(10), 'something else')
As the flow first tests the 1st/Furthest Left REPLACE statement, then upon failure will continue to test the next REPLACE statement.