How can I see all the special characters permissible in a varchar or char field in SQL Server?
You probably just need to see the ASCII
and EXTENDED ASCII
character sets. As far as I know any of these are allowed in a char
/varchar
field.
If you use nchar
/nvarchar
then it's pretty much any character in any unicode set in the world.
Find all special characters in a column in SQL Server 2008
Negatives are your friend here:
SELECT Col1
FROM TABLE
WHERE Col1 like '%[^a-Z0-9]%'
Which says that you want any rows where Col1
consists of any number of characters, then one character not in the set a-Z0-9, and then any number of characters.
If you have a case sensitive collation, it's important that you use a range that includes both upper and lower case A
, a
, Z
and z
, which is what I've given (originally I had it the wrong way around. a
comes before A
. Z
comes after z
)
Or, to put it another way, you could have written your original WHERE
as:
Col1 LIKE '%[!@#$%]%'
But, as you observed, you'd need to know all of the characters to include in the []
.
Identify Special Characters and numbers in SQL
If you want the results just printed out, you can use:
DECLARE @StringVal VARCHAR(400) = 'Test1@abc';
DECLARE @expres VARCHAR(MAX) = '%[^a-zA-Z_]%';
WHILE @StringVal LIKE @expres
BEGIN
PRINT SUBSTRING(@stringVal, PATINDEX(@expres, @stringVal), 1);
SET @stringval = STUFF(@stringVal, 1, PATINDEX(@expres, @stringVal), '');
END;
If you want them output as a string, you can concatenate them:
DECLARE @StringVal VARCHAR(400) = 'Test1@abc';
DECLARE @expres VARCHAR(MAX) = '%[^a-zA-Z_]%';
DECLARE @output VARCHAR(MAX) = '';
WHILE @StringVal LIKE @expres
BEGIN
SET @output = @output + SUBSTRING(@stringVal, PATINDEX(@expres, @stringVal), 1);
SET @stringval = STUFF(@stringVal, 1, PATINDEX(@expres, @stringVal), '');
END;
SELECT @output;
Here is a db<>fiddle.
How can I support special characters in SQL Server?
Have you tried "nvarchar". Change the field/fields into nvarchar instead of varchar where you are doubting special characters will come. Or make the table Collation to utf8_general_ci
How to detect if a string contains special characters?
Assuming SQL Server:
e.g. if you class special characters as anything NOT alphanumeric:
DECLARE @MyString VARCHAR(100)
SET @MyString = 'adgkjb$'
IF (@MyString LIKE '%[^a-zA-Z0-9]%')
PRINT 'Contains "special" characters'
ELSE
PRINT 'Does not contain "special" characters'
Just add to other characters you don't class as special, inside the square brackets
Checking if a string is valid with special chars
Escaping is one method.
But if you just want to ignore the readable ASCII characters, then the range could be simplified.
[^ -~]
: not between space and ~
-- Sample data
declare @T table (col NVARCHAR(30) collate SQL_Latin1_General_CP850_BIN primary key);
insert into @T (col) values
(N'abc╢123'),
(N'xyz123[}'''),
(N'abc௹123');
-- Query
SELECT col, PATINDEX(N'%[^ -~]%' collate SQL_Latin1_General_CP850_BIN, col) as pos
FROM @T;
Returns:
col pos
-------- ----
abc╢123 4
abc௹123 4
xyz123[}' 0
But to also locate the caret and some others, it's more complicated.
Since PATINDEX doesn't have ESCAPE as LIKE does.
-- Sample data
declare @T table (
id int identity(1,1) primary key,
col NVARCHAR(30) collate SQL_Latin1_General_CP850_BIN
);
insert into @T (col) values
(N'xyz[123]}''') -- good
,(N'abc╢123') -- bad
,(N'abc௹123') -- bad
,(N'def#456') -- bad
,(N'def^456') -- bad
;
-- also locate #, ´ , ` and ^
SELECT col,
CASE
WHEN PATINDEX(N'%[^ !"$-_a-z{-~]%' collate SQL_Latin1_General_CP850_BIN, col) > 0
THEN PATINDEX(N'%[^ !"$-_a-z{-~]%' collate SQL_Latin1_General_CP850_BIN, col)
ELSE CHARINDEX(N'^' collate SQL_Latin1_General_CP850_BIN, col)
END AS pos
FROM @T;
Returns:
xyz[123]}' 0
abc╢123 4
abc௹123 4
def#456 4
def^456 4
How to replace all special characters in string
You can create a User-Defined-Function for something like that.
Then use the UDF in the update.
CREATE FUNCTION [dbo].LowerDashString (@str varchar(255))
RETURNS varchar(255)
AS
BEGIN
DECLARE @result varchar(255);
DECLARE @chr varchar(1);
DECLARE @pos int;
SET @result = '';
SET @pos = 1;
-- lowercase the input and remove the single-quotes
SET @str = REPLACE(LOWER(@str),'''','');
-- loop through the characters
-- while replacing anything that's not a letter to a dash
WHILE @pos <= LEN(@str)
BEGIN
SET @chr = SUBSTRING(@str, @pos, 1)
IF @chr LIKE '[a-z]' SET @result += @chr;
ELSE SET @result += '-';
SET @pos += 1;
END;
-- SET @result = TRIM('-' FROM @result); -- SqlServer 2017 and beyond
-- multiple dashes to one dash
WHILE @result LIKE '%--%' SET @result = REPLACE(@result,'--','-');
RETURN @result;
END;
GO
Example snippet using the function:
-- using a table variable for demonstration purposes
declare @SomeInfo table (Id int primary key identity(1,1) not null, InfoCode varchar(100) not null);
-- sample data
insert into @SomeInfo (InfoCode) values
('Cathe Friedrich''s Low Impact'),
('coffeyfit-cardio-box-&-burn'),
('Jillian Michaels: Cardio'),
('Sleek Technique™'),
('The Dancer''s-workout®');
update @SomeInfo
set InfoCode = dbo.LowerDashString(InfoCode)
where (InfoCode LIKE '%[^A-Z-]%' OR InfoCode != LOWER(InfoCode));
select *
from @SomeInfo;
Result:
Id InfoCode
-- -----------------------------
1 cathe-friedrichs-low-impact
2 coffeyfit-cardio-box-burn
3 jillian-michaels-cardio
4 sleek-technique-
5 the-dancers-workout-
Find non-ASCII characters in varchar columns using SQL Server
try something like this:
DECLARE @YourTable table (PK int, col1 varchar(20), col2 varchar(20), col3 varchar(20));
INSERT @YourTable VALUES (1, 'ok','ok','ok');
INSERT @YourTable VALUES (2, 'BA'+char(182)+'D','ok','ok');
INSERT @YourTable VALUES (3, 'ok',char(182)+'BAD','ok');
INSERT @YourTable VALUES (4, 'ok','ok','B'+char(182)+'AD');
INSERT @YourTable VALUES (5, char(182)+'BAD','ok',char(182)+'BAD');
INSERT @YourTable VALUES (6, 'BAD'+char(182),'B'+char(182)+'AD','BAD'+char(182)+char(182)+char(182));
--if you have a Numbers table use that, other wise make one using a CTE
WITH AllNumbers AS
( SELECT 1 AS Number
UNION ALL
SELECT Number+1
FROM AllNumbers
WHERE Number<1000
)
SELECT
pk, 'Col1' BadValueColumn, CONVERT(varchar(20),col1) AS BadValue --make the XYZ in convert(varchar(XYZ), ...) the largest value of col1, col2, col3
FROM @YourTable y
INNER JOIN AllNumbers n ON n.Number <= LEN(y.col1)
WHERE ASCII(SUBSTRING(y.col1, n.Number, 1))<32 OR ASCII(SUBSTRING(y.col1, n.Number, 1))>127
UNION
SELECT
pk, 'Col2' BadValueColumn, CONVERT(varchar(20),col2) AS BadValue --make the XYZ in convert(varchar(XYZ), ...) the largest value of col1, col2, col3
FROM @YourTable y
INNER JOIN AllNumbers n ON n.Number <= LEN(y.col2)
WHERE ASCII(SUBSTRING(y.col2, n.Number, 1))<32 OR ASCII(SUBSTRING(y.col2, n.Number, 1))>127
UNION
SELECT
pk, 'Col3' BadValueColumn, CONVERT(varchar(20),col3) AS BadValue --make the XYZ in convert(varchar(XYZ), ...) the largest value of col1, col2, col3
FROM @YourTable y
INNER JOIN AllNumbers n ON n.Number <= LEN(y.col3)
WHERE ASCII(SUBSTRING(y.col3, n.Number, 1))<32 OR ASCII(SUBSTRING(y.col3, n.Number, 1))>127
order by 1
OPTION (MAXRECURSION 1000);
OUTPUT:
pk BadValueColumn BadValue
----------- -------------- --------------------
2 Col1 BA¶D
3 Col2 ¶BAD
4 Col3 B¶AD
5 Col1 ¶BAD
5 Col3 ¶BAD
6 Col1 BAD¶
6 Col2 B¶AD
6 Col3 BAD¶¶¶
(8 row(s) affected)
Related Topics
MySQL Returning the Top 5 of Each Category
How to Pivot Rows into Columns (Custom Pivoting)
Access to Result Sets from Within Stored Procedures Transact-SQL SQL Server
Oracle: Loading a Large Xml File
SQL Server: Drop Table Cascade Equivalent
SQL Pivot and String Concatenation Aggregate
Does Postgres Support Nested or Autonomous Transactions
Comma Separated Values in a Database Field
How to Remove Redundant Namespace in Nested Query When Using for Xml Path
Casting Null Type When Updating Multiple Rows
How to Cast Variables in T-SQL for Bulk Insert
Using Excel Vba to Run SQL Query
Optimized SQL for Tree Structures
How to Insert a Blob into a Database Using SQL Server Management Studio
How to Kill a Running Select Statement
How to Make a Composite Key with SQL Server Management Studio