DECLARE @STRINGTOLOOKFOR VARCHAR(500)
,@TABLENAME SYSNAME
,@FULLTABLENAME SYSNAME
--<-- Give the value to search------->
SELECT @STRINGTOLOOKFOR = '7F0B0DD5-22BC-421B-9416-3A7C24146A98'
--<-- Give the value to search------->
DECLARE @COLUMNNAME NVARCHAR(128),
@DATETYPE NVARCHAR(128),
@ROW SMALLINT,
@ROWCOUNT INT,
@SQL NVARCHAR(1000)
DECLARE STRING_FIND_CURSOR CURSOR FAST_FORWARD FOR
SELECT TABLE_NAME, TABLE_SCHEMA+'.'+TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE ='BASE TABLE'
OPEN STRING_FIND_CURSOR
FETCH NEXT FROM STRING_FIND_CURSOR
INTO @TABLENAME, @FULLTABLENAME
SET @STRINGTOLOOKFOR = @STRINGTOLOOKFOR
WHILE @@FETCH_STATUS = 0
BEGIN
SET @ROW = 1
SELECT @ROWCOUNT = MAX([ORDINAL_POSITION])
FROM [INFORMATION_SCHEMA].[COLUMNS]
WHERE [TABLE_NAME] = @TABLENAME
GROUP BY [ORDINAL_POSITION]
WHILE @ROW <= @ROWCOUNT
BEGIN
SELECT @COLUMNNAME = QUOTENAME(COLUMN_NAME) ,
@DATETYPE = [DATA_TYPE]
FROM [INFORMATION_SCHEMA].[COLUMNS]
WHERE [TABLE_NAME] = @TABLENAME
AND [ORDINAL_POSITION] = @ROW
ORDER BY [ORDINAL_POSITION]
SET @ROW = @ROW + 1
SET @SQL = NULL
IF @DATETYPE IN ( N'CHAR', N'VARCHAR', N'TEXT')
SET @SQL = 'SELECT * FROM ' + @FULLTABLENAME + ' WHERE PATINDEX(''%' + @STRINGTOLOOKFOR + '%'', ' + @COLUMNNAME + ') > 0'
IF @DATETYPE IN (N'UNIQUEIDENTIFIER') AND @STRINGTOLOOKFOR LIKE '[A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][-][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][-][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][-][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][-][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9][A-F,0-9]'
SET @SQL = 'SELECT * FROM ' + @FULLTABLENAME + ' WHERE' + @COLUMNNAME + ' = ''' + @STRINGTOLOOKFOR + ''''
IF @DATETYPE IN (N'NCHAR', N'NVARCHAR', N'NTEXT')
SET @SQL = 'SELECT * FROM ' + @FULLTABLENAME + ' WHERE PATINDEX(''%' + @STRINGTOLOOKFOR + '%'', CAST(' + @COLUMNNAME + ' AS TEXT)) > 0'
IF @DATETYPE IN (N'SQL_VARIANT',N'SMALLINT',N'INT',N'BIGINT',N'TINYINT')
SET @SQL = 'SELECT * FROM ' + @FULLTABLENAME + ' WHERE CONVERT(VARCHAR(8000),' + @COLUMNNAME + ') LIKE ''%'+ @STRINGTOLOOKFOR + '%'''
IF @SQL IS NOT NULL
BEGIN
SET @SQL = 'IF EXISTS(' + @SQL + ') PRINT ''SELECT '+@COLUMNNAME+' FROM ' + @FULLTABLENAME + ' WHERE ' + @COLUMNNAME + ' LIKE ''''%'+@STRINGTOLOOKFOR+'%'''''''
EXEC (@SQL)
END
END
FETCH NEXT FROM STRING_FIND_CURSOR
INTO @TABLENAME, @FULLTABLENAME
END
CLOSE STRING_FIND_CURSOR
DEALLOCATE STRING_FIND_CURSOR
Month: March 2020
Building a comma separated string is a very frequent&common requirement for SQL Server developers. Developers find different ways to achieve this like CLR/XML PATH/Co-related queries etc. With this post, we are going to see two options that are widely used XML PATH & string_AGG and a quick look at its performance comparison.
— Using STUFF & XML PATHThis is the most widely used method to build the comma separated string. In my personal experience, I observed many performance issues related to this method for a large set of data.
Drop Table if exists BuildCommaSeparatedString
Create Table BuildCommaSeparatedString(SessionID int, CourseID varchar(100))
Insert into BuildCommaSeparatedString Values
(1,'English'),(1,'Maths'),(1,'Accountancy'),(2,'History'),(2,'Biology')
SELECT SessionID,STUFF((SELECT ',' + CourseID FROM BuildCommaSeparatedString EE
WHERE EE.SessionID=E.SessionID
ORDER BY CourseID -- To order the Courses in order
FOR XML PATH('')), 1, 1, '') AS 'CommaseparatedString'
FROM BuildCommaSeparatedString E
GROUP BY E.SessionID
— Using string_AGG in SQL Server 2017
With SQL Server 2017 release, there is a better way to do this using string_agg built-in function. The STRING_AGG() is an aggregate function that concatenates rows of strings into a single string, separated by a specified separator.
STRING_AGG ( input_string, separator ) [ order_clause ]
input_string - is the column name of any type that can convert to a comma separated string
separator - is the separator caharacter like , or ; etc
[ order_clause ] - specifies the sort order of concatenated results using WITHIN GROUP clause
WITHIN GROUP ( ORDER BY expression [ ASC | DESC ] )
Please note that, The STRING_AGG() ignores NULL and it does not add the separator for NULL when performing concatenation.
Drop Table if exists BuildCommaSeparatedString
Create Table BuildCommaSeparatedString(SessionID int, CourseID varchar(100))
Insert into BuildCommaSeparatedString Values
(1,'English'),(1,'Maths'),(1,'Accountancy'),(2,'History'),(2,'Biology')
Select SessionID, STRING_AGG(CourseID,',') From BuildCommaSeparatedString Group by SessionID
--To build the comma separated string in an order way
Select SessionID, STRING_AGG(CourseID,',') within group (Order by CourseID asc)
From BuildCommaSeparatedString Group by SessionID
A quick look on Performance benefit
The below snapshot clearly indicates that the performance benefit of string_AGG built-in function over XML PATH approach.
Conclusion
If you are in SQL Server 2017 – use built-in function string_AGG instead of any other method. I have seen this outperform many times than a custom built code. If you do not agree or have any different experience, please share the specific case with an example for the benefits of readers. Thanks in advance!
Today, we are going to see a scenario where we need to remove special characters from a string in SQL Server. Let us discuss on few methods to achieve this “extended” trim functionality.
1. Option: Using REPLACEREPLACE function can be effectively used to replace the special characters.
Script:
DECLARE @BaddataString NVARCHAR(max);
SET @BaddataString = 'my '+
CHAR(10)+CHAR(10)+CHAR(10) +
'text ' +
CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32) +
' ' +
CHAR(10)+CHAR(10)+CHAR(10);
SELECT
@BaddataString,
LEN(@BaddataString)
, REPLACE(REPLACE(REPLACE(RTRIM(@BaddataString),CHAR(9), ''),CHAR(10),''),CHAR(13),'') ,
LEN(REPLACE(REPLACE(REPLACE(RTRIM(@BaddataString),CHAR(9), ''),CHAR(10),''),CHAR(13),''))
Here is the output of the below code:
2. Option: Using CDATA Another effective option to use CDATA method.Script
/*
The below function replaces special characters like invisible TAB, Carriage Return, and Line Feed characters.
*/
CREATE FUNCTION dbo.FN_RemoveBadCharacter(@input VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN (SELECT CAST('' AS XML).value('(/r/text())[1] cast as xs:token?','VARCHAR(MAX)'));
END
GO
DECLARE @BaddataString NVARCHAR(max);
SET @BaddataString = 'my '+
CHAR(10)+CHAR(10)+CHAR(10) +
'text ' +
CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32) +
' ' +
CHAR(10)+CHAR(10)+CHAR(10);
SELECT @BaddataString,
LEN(@BaddataString)
, dbo.FN_RemoveBadCharacter(@BaddataString),
LEN(dbo.FN_RemoveBadCharacter(@BaddataString))
Here is the output of the below code:
3. Option: Using CLR to define a function to removeThere are certain things its best to do at application code rather than T-SQL. SQL Server may not be the best place to formatting string, date etc. There will be lots of available resources just away from a google search.
Hope, you enjoy this post, please share your thoughts as always!


