LearnItFirst User Forum

New SQL Server 2008 DBA Course
Welcome Guest Search | New Posts | Members | Log In | Register

SQL Script to Search All Tables and All Columns for Specified String Search Term Options
Scott Whigham
Posted: Tuesday, June 05, 2007 1:33:06 PM


Rank: Super Mod

Joined: 3/20/2006
Posts: 440
Points: 936
Where do you live?: Dallas, TX
I needed to do this today in a small database and wrote this little proc. It can definitely be improved but, since I'm more concerned with "getting things done" at the moment than performance optimizations, it is what it is Smile It runs over my 100MB test database in 3 seconds so it's good enough for what I need. Please post any improvements you find! I'm pretty sure we could morph this to a recursive CTE but I don't want to think that deep Smile
Code:
/*
    Author: Scott Whigham FROM http://www.LearnSqlServer.com/

    Description: Queries every string-based column (VARCHAR/NVARCHAR/CHAR/NCHAR only) to see if the column contains the @SearchTerm

    Versions: SQL Server 2000+

    Creation Date: June 5, 2007

    For more scripts like this one, visit http://forums.learnsqlserver.com/codesamples.aspx
*/
CREATE PROC SearchForTermInAllStringColumnsInDatabase (
    @SearchTerm VARCHAR(1024)
    , @Collation SYSNAME = 'SQL_Latin1_General_CP1_CI_AS' -- Only here so that we can decide if the caller wants a case or language-sensitive search

AS
DECLARE @ColumnsToSearch TABLE (
    LineId INT NOT NULL IDENTITY(1,1) PRIMARY KEY
    , SchemaName SYSNAME NOT NULL
    , TableName SYSNAME NOT NULL
    , ColumnName SYSNAME NOT NULL
)
SET NOCOUNT ON

-- Step 1: What is the LEN(@SearchTerm)?
DECLARE @LengthOfSearchTerm INT
SET @LengthOfSearchTerm = LEN(@SearchTerm)

-- Step 2: Find all string-based columns with a column length > @LengthOfSearchTerm
INSERT @ColumnsToSearch (SchemaName, TableName, ColumnName)
SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c JOIN INFORMATION_SCHEMA.TABLES t
    ON c.TABLE_SCHEMA=t.TABLE_SCHEMA
    AND c.TABLE_NAME = t.TABLE_NAME
WHERE t.TABLE_TYPE = 'BASE TABLE'
    AND c.DATA_TYPE IN ('varchar', 'nvarchar','char', 'nchar')
    AND c.CHARACTER_MAXIMUM_LENGTH >= @LengthOfSearchTerm

-- Search every column!
DECLARE @LineId INT, @FullyQualifiedTableName NVARCHAR(256), @ColumnToSearch SYSNAME, @Sql NVARCHAR(1024)

SELECT @LineId = LineId, @FullyQualifiedTableName = '[' + SchemaName + '].[' + TableName + ']', @ColumnToSearch = '[' + ColumnName + ']' FROM @ColumnsToSearch

WHILE @LineId IS NOT NULL
    BEGIN
        -- Create the base query against the table
  SET @Sql = 'SELECT ''' + @FullyQualifiedTableName + '.' + @ColumnToSearch + ''' AS [Table_Column], * FROM '
        + @FullyQualifiedTableName + ' WHERE ' + @ColumnToSearch + ' LIKE ''%' + @SearchTerm + '%'' COLLATE ' + @Collation

        -- Only return rows that actually contain the search term otherwise write out a message saying the table/column did not have the criteria
        EXEC ( 'IF NOT EXISTS (' + @Sql + ') PRINT ''' + @FullyQualifiedTableName + '.' + @ColumnToSearch + ' - no matches'' ELSE ' + @Sql)

        DELETE @ColumnsToSearch WHERE LineId=@LineId
        SET @LineId = NULL
        SELECT @LineId = LineId, @FullyQualifiedTableName = '[' + SchemaName + '].[' + TableName + ']', @ColumnToSearch = '[' + ColumnName + ']' FROM @ColumnsToSearch
    END
GO
EXEC SearchForTermInAllStringColumnsInDatabase 'sevrer'
Scott Whigham
Posted: Tuesday, June 05, 2007 2:09:29 PM


Rank: Super Mod

Joined: 3/20/2006
Posts: 440
Points: 936
Where do you live?: Dallas, TX
I also modded mine to make it accept an extra parameter called @ColumnsToIgnore which is basically a CSV array ofcolumns not to check. I didn't include it here simply because it references a SQL Split function that I have but I can post it if anyone wants it...
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.