We recently migrated from SQL Server 2012 to SQL Server 2014 and all our FOR XML
code started throwing errors about non-printable ASCII characters. I wrote this horrible function to remove non-printable ASCII characters as a quick fix. I want to replace it with something cleaner. Is there a way to do this?
ALTER FUNCTION [dbo].[remove_non_printable_chars]
(@input_string nvarchar(max))
RETURNS nvarchar(max)
BEGIN
RETURN
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(REPLACE(REPLACE(REPLACE(
REPLACE(REPLACE(@input_string,
CHAR(1), ''),CHAR(2), ''),CHAR(3), ''),CHAR(4), ''),CHAR(5), ''),CHAR(6), ''),CHAR(7), ''),CHAR(8), ''),CHAR(9), ''),CHAR(10), ''),
CHAR(11), ''),CHAR(12), ''),CHAR(13), ''),CHAR(14), ''),CHAR(15), ''),CHAR(16), ''),CHAR(17), ''),CHAR(18), ''),CHAR(19), ''),CHAR(20), ''),
CHAR(21), ''),CHAR(22), ''),CHAR(23), ''),CHAR(24), ''),CHAR(25), ''),CHAR(26), ''),CHAR(27), ''),CHAR(28), ''),CHAR(29), ''),CHAR(30), ''),
CHAR(31), ''), NCHAR(0) COLLATE Latin1_General_100_BIN2, '')
END
Here's the FOR XML
code that broke. (I did not write this. It was already in the code base).
SELECT @HTMLTableData =
(
SELECT HTMLRows
FROM (
SELECT N'<tr>' + HTMLRow + N'</tr>' AS HTMLRows
FROM @HTMLRowData
) mi
FOR XML PATH(''), TYPE
).value('/', 'NVARCHAR(MAX)')
4条答案
按热度按时间6rvt4ljy1#
Another Option.
This function will replace control characters and correct any residual repeating spaces. For example
Jane Smith{13}was here
will not be returned asJane Smithwas here
, but ratherJane Smith was here
olmpazwi2#
In-line version:
And use it like so:
or
Reference:
lrl1mhuk3#
Here is a similar answer of the previous inline-table valued function answer ( https://stackoverflow.com/a/43148897/2864740 ) for this question. The primary change is this uses a
patindex
guard first and is much faster when only a small percentage of the rows contain characters that need to be replaced.Thus the two huge improvements from the original scalar function:
patindex
for an initial guard check. This changes the number of characters SQL must exmine when there are no control characters to replace fromO(n * num_replace_calls)
to~O(n)
. Since most of the data data (in my case) contains no control characters, this can result in a huge performance increase.In a query:
mlnl4t2r4#
Just extending the previous answers a little bit
Below the white-list characters, all the others chars will be cleared
I know it's ugly but it works.
Use for data clean up
Adjust your datatype (nvarchar or varchar + max) as required
If you want to add more chars to clear use "select ASCII('char to remove here')" MSSQL command in order to get the ASCII code of the char and put it inside the replace instruction
i.g SELECT ASCII('¢') returns 162
so add one more "REPLACE(" after "RETURN" and "CHAR(162), '')" at the end of line but before the ";" sign.