T-SQL脚本在数据库中搜索字符串并显示表名和记录

时间:2017-06-11 23:10:38

标签: sql-server tsql

我有一个脚本,它将在数据库中搜索字符串并列出表名和列。我需要让它不仅列出列而是列出整个记录,以便我可以比较文本中的帐户。如何更改脚本以显示整个记录而不仅仅是列?

USE powercampustest
DECLARE @SearchStr nvarchar(100) = '93335' --Five,Test
DECLARE @Results TABLE (ColumnName nvarchar(370), ColumnValue nvarchar(3630))

SET NOCOUNT ON

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET  @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

WHILE @TableName IS NOT NULL

BEGIN
    SET @ColumnName = ''
    SET @TableName = 
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM     INFORMATION_SCHEMA.TABLES
        WHERE         TABLE_TYPE = 'BASE TABLE'
            AND    QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
            AND    OBJECTPROPERTY(
                    OBJECT_ID(
                        QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
                         ), 'IsMSShipped'
                           ) = 0
    )

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)

    BEGIN
        SET @ColumnName =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM     INFORMATION_SCHEMA.COLUMNS
            WHERE         TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                AND    TABLE_NAME    = PARSENAME(@TableName, 1)
                AND    DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
                AND    QUOTENAME(COLUMN_NAME) > @ColumnName
        )

        IF @ColumnName IS NOT NULL

        BEGIN
            INSERT INTO @Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                FROM ' + @TableName + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END    
END

SELECT ColumnName, ColumnValue FROM @Results

    /*
    ColumnName  ColumnValue
    [dbo].[ADDRESS].[PEOPLE_ORG_CODE_ID]    P000092436
    [dbo].[ADDRESS].[PEOPLE_ORG_ID] 000092436
    [dbo].[ADDRESSHIERARCHYUNIQUE].[PEOPLE_ORG_CODE_ID] P000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_CODE_ID]    P000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_CODE_ID]    P000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_CODE_ID]    P000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_CODE_ID]    P000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_ID] 000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_ID] 000092436
    [dbo].[ADDRESSSCHEDULE].[PEOPLE_ORG_ID] 000092436

1 个答案:

答案 0 :(得分:0)

首先,你现在拥有的剧本有点不好 循环几乎从来都不是SQL中的正确方法,嵌套循环甚至是最差的。

其次,由于您正在搜索数据库中的所有表,因此获取整行行内容的最佳选择是XML。这样,您就可以拥有一个只包含3列的表格,以保留所需的所有信息:ColumnNameColumnValueRowContent
它还可以让您使用基于集合的方法并松开循环。

首先,您声明搜索参数和将保存查询的变量:

DECLARE @SearchStr nvarchar(100) = 'P000092436',
        @SQL nvarchar(max) = ''

然后,您使用Information_schema.ColumnsInformation_schema.Tables的内置视图来创建查询:

SELECT @SQL = @SQL + 
'UNION 
SELECT '''+ QUOTENAME(t.TABLE_SCHEMA) +'.'+ QUOTENAME(c.TABLE_NAME) +'.'+ QUOTENAME(c.COLUMN_NAME) +''' As ColumnName, -- This gets you the full column name
'''+ @SearchStr +''' As ColumnValue,
(SELECT * FROM '+ QUOTENAME(c.TABLE_NAME) +' WHERE '+ QUOTENAME(c.COLUMN_NAME) +' LIKE ''%'+ @SearchStr +'%'' FOR XML AUTO) -- This gets you the row content
FROM '+ QUOTENAME(c.TABLE_NAME) +' 
WHERE '+ QUOTENAME(c.COLUMN_NAME) +' LIKE ''%'+ @SearchStr +'%''
'
FROM INFORMATION_SCHEMA.COLUMNS c
INNER JOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_NAME = t.TABLE_NAME
WHERE t.TABLE_TYPE = 'BASE TABLE'

然后,使用STUFF删除第一个UNION

SET @SQL = STUFF(@SQL, 1, 7, '')

不,这将创建的查询是这样的:

SELECT '[schema].[table1].[column1]' As ColumnName, 
'P000092436' As ColumnValue,
(SELECT * FROM [table1] WHERE [column1] LIKE '%P000092436%' FOR XML AUTO)
FROM [table1] 
WHERE [column1] LIKE '%P000092436%'
UNION 
SELECT '[schema].[table1].[column2]' As ColumnName, 
'P000092436' As ColumnValue,
(SELECT * FROM [table1] WHERE [column2] LIKE '%P000092436%' FOR XML AUTO)
FROM [table1] 
WHERE [column2] LIKE '%P000092436%'
UNION....

包括所有表格和所有列。

下一步是创建临时表来保存结果:

CREATE TABLE #SearchResults
(
    ColumnName nvarchar(500), 
    ColumnValue nvarchar(100), 
    RowContent xml
)

并将此查询的结果插入其中:

INSERT INTO #SearchResults
EXEC(@SQL)

You can see a live demo on Rextester.