如何使用临时存储过程在SQL中通过数据库的所有表搜索值?

时间:2019-06-10 18:10:41

标签: sql sql-server database

我有多个数据库,我想创建一个临时存储过程(##SearchAllTables),该过程在数据库的所有表中搜索值。

我面临的问题是,如果我针对master数据库创建了临时存储过程,那么当我针对另一个数据库运行它时,它将不起作用,因为它不会显示任何发现。

如果我针对那个特定的数据库创建了相同的临时存储过程,它将正常工作。

我正在使用此网站上的存储过程: https://thesitedoctor.co.uk/blog/search-every-table-and-field-in-a-sql-server-database-updated/

你知道我为什么有这种行为吗?

2 个答案:

答案 0 :(得分:0)

查看存储过程,似乎将过程代码第33行的此过滤器应用于master数据库时会出现问题:

OBJECTPROPERTY(
    OBJECT_ID(
        QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
        ), 'IsMSShipped'
            ) = 0

master数据库中的表都随MS SQL安装一起提供,因此将具有等于1的IsMSShipped属性,因此将其排除在搜索之外。您可以通过运行以下命令进行测试:

select
    *,
    OBJECTPROPERTY(OBJECT_ID(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)), 'IsMSShipped')
from
    master.INFORMATION_SCHEMA.TABLES

如果要搜索这些表,请从WHERE子句中删除该过滤器。

答案 1 :(得分:0)

免责声明:这是您要执行的非常繁重的任务。我不建议在生产环境中运行。

您所引用的代码仅用于查询当前数据库中的表。

INFORMATION_SCHEMA.TABLES

  

为当前用户拥有权限的当前数据库中的每个表或视图返回一行。

如果希望它为每个数据库运行,则必须对其进行修改以遍历所有数据库。像这样:

DECLARE @dbName  NVARCHAR(256)

DECLARE db_cursor CURSOR FOR
SELECT name
FROM sys.databases
WHERE state_desc = 'ONLINE'

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @dbName

WHILE @@FETCH_STATUS = 0
BEGIN
    --Code from proc here
END

然后,您需要修改将@TableName变量放在一起以包含数据库名称的查询:

...

BEGIN
    SET @ColumnName = ''
    SET @TableName = 
    (
        SELECT QUOTENAME(@dbName)+ '.' + 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)

 ...