2017-04-13 100 views
3

考虑的主键有一个表像命名为:人民查找值,显示我的数据库,表,列,找到价值

| Id | Name | Code | 
| 1  | John | 857 | 
| 2  | Mike | 893 | 
| 3  | Sara | 935 | 

此表是PEOPLEDB表。

问题是:

我想找到'Mike'关键字。 情况: 我不知道去搜索哪个数据库,表格。

我需要一个T-SQL查询,以搜索所有数据库和表我显示了这个:

| Id | DatabaseName | TableName | ColumnName | Pk | SearchValue 
| 1 | 'PeopleDb' | 'People' | 'Name'  | 2 | 'Mike' 

我不知道如何编写查询所有数据库和表进行搜索。

任何帮助将不胜感激。


编辑:

速度是不是这里的问题,我必须这样做。

我试过这个查询,我想要的是相同的,但是搜索所有的数据库。

CREATE PROC SearchAllTables 
(
    @SearchStr nvarchar(100) 
) 
AS 
BEGIN 

-- Copyright © 2002 Narayana Vyas Kondreddi.All rights reserved. 
-- Purpose: To search all columns of all tables for a given search string 
-- Written by: Narayana Vyas Kondreddi 
-- Site: http://vyaskn.tripod.com 
-- Tested on: SQL Server 7.0 and SQL Server 2000 
-- Date modified: 28th July 2002 22:50 GMT 

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') 
       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 
END 

更新:

我需要一个工作的T-SQL,搜索所有数据库,表,列所有类型的变量。 当前答案在某些情况下不起作用,如nvarchar字段中的连接字符串。

+2

我想你会需要动态SQL为此。 –

+0

我只想把它作为一个t-sql查询在sql server中自己运行它。 –

+0

试着在这里找到你的答案: http://stackoverflow.com/questions/436351/how-do-i-find-a-value-anywhere-in-a-sql-server-database –

回答

2

我已经更新了你的逻辑按以下和正常工作,请看看:

DECLARE @SearchStr VARCHAR(50)='Surat' 

DECLARE @Results TABLE(DatabaseName NVARCHAR(500), TableName nvarchar(370),ColumnName nvarchar(370), ColumnValue nvarchar(3630),PrimaryKey nvarchar(200), PrimaryKeyValue nvarchar(4000)) 

SET NOCOUNT ON 

DECLARE @TableList AS Table 
(
    TableName VARCHAR(500), 
    RowNo INT 
) 

DECLARE @ColumnList AS Table 
(
    ColumnName VARCHAR(500), 
    RowNo INT 
) 

DECLARE @PrimaryKeyList AS Table 
(
    PrimaryKeyName VARCHAR(500) 
) 

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

DECLARE @DatabaseCount INT=0, @Index INT=0, @DatabaseName NVARCHAR(500), @TotalColumnCount INT, @ColumnIndex INT=0, @TotalTableCount INT, @TableIndex INT=0 

SELECT 
    *, 
    ROW_NUMBER() OVER (ORDER BY name) AS RowNo 
INTO #tblDatabases 
FROM Sys.Databases 
WHERE name NOT IN ('master','model','msdb','tempdb') 

SELECT @DatabaseCount=COUNT (*) FROM #tblDatabases 
WHILE @Index<@DatabaseCount 
BEGIN 
    SET @[email protected]+1 
    SELECT @DatabaseName='',@TableIndex=0,@ColumnIndex=0,@TableName='',@ColumnName='' 
    SELECT @DatabaseName=name FROM #tblDatabases WHERE [email protected]  

    DELETE FROM @TableList 
    INSERT INTO @TableList 
    EXEC(' 
      SELECT QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME), 
       ROW_NUMBER() OVER (ORDER BY TABLE_NAME) 
      FROM ['[email protected]+'].INFORMATION_SCHEMA.TABLES 
      WHERE TABLE_TYPE = ''BASE TABLE'' 
     ') 

    SELECT @TotalTableCount=COUNT(*) FROM @TableList 

    WHILE @TableIndex<@TotalTableCount 
    BEGIN 

     SET @[email protected]+1 
     SELECT @ColumnName = '',@ColumnIndex=0 

     SELECT @TableName=TableName FROM @TableList WHERE [email protected]    
     SET @CurrentTableName=REPLACE(REPLACE(REPLACE(@TableName,'[dbo].',''),'[',''),']','') 

     DELETE FROM @ColumnList 
     INSERT INTO @ColumnList 
     EXEC('SELECT 
       COLUMN_NAME,ROW_NUMBER() OVER (ORDER BY COLUMN_NAME) 
        FROM ['[email protected]+'].INFORMATION_SCHEMA.COLUMNS 
       WHERE TABLE_SCHEMA = PARSENAME('''[email protected]+''', 2) 
        AND TABLE_NAME = PARSENAME('''[email protected]+''', 1) 
        AND DATA_TYPE IN (''char'', ''varchar'', ''nchar'', ''nvarchar'') 


     ') 

     SELECT @TotalColumnCount=COUNT(*) FROM @ColumnList 

     WHILE @ColumnIndex<@TotalColumnCount 
     BEGIN 
      SET @[email protected]+1 
      SET @ColumnName='' 
      SELECT @ColumnName=ColumnName FROM @ColumnList WHERE [email protected]   

      DELETE FROM @PrimaryKeyList 
      INSERT INTO @PrimaryKeyList 
      EXEC(' 
        SELECT Col.Column_Name from 
         ['[email protected]+'].INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, 
         ['[email protected]+'].INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col 
        WHERE 
         Col.Constraint_Name = Tab.Constraint_Name 
         AND Col.Table_Name = Tab.Table_Name 
         AND Constraint_Type = ''PRIMARY KEY'' 
         AND Col.Table_Name= '''[email protected]+'''   
       ') 

      SELECT @PrimaryKey='' 
      SELECT @PrimaryKey=PrimaryKeyName FROM @PrimaryKeyList 
      SET @PrimaryKey=ISNULL(@PrimaryKey,'') 

      IF @ColumnName IS NOT NULL AND @PrimaryKey<>'' 
      BEGIN 
       INSERT INTO @Results 
       EXEC 
       (
        'SELECT '''[email protected]+''','''[email protected]+''',''' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) , '''[email protected]ryKey+''', [' + @PrimaryKey + '] 
        FROM ['[email protected]+'].' + @TableName + ' (NOLOCK) ' + 
        ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
       ) 
      END 
     END 
    END 
END 


SELECT ROW_NUMBER() OVER (ORDER BY DatabaseName) AS Id,DatabaseName,TableName,ColumnName, ColumnValue AS SearchValue,PrimaryKeyValue AS Pk, PrimaryKey FROM @Results 

DROP TABLE #tblDatabases 
+0

这一个工作正常,但在某些情况下不起作用:我有一个连接字符串值的列:Server = localhost; DataBase = Propanel; UID = sa; pwd = silver; multipleactiveresultsets = True。当我搜索'sil','silver','pwd'或其他类似的查询无法找到这个对我来说? –

+0

我已经在一列中使用你的价值,并通过'sil'进行搜索,它对我有用 –

+0

好的,谢谢你<3。我会选择你的答案作为迄今为止被接受的最佳答案。 –

1
SELECT * FROM all_objects where object_name = 'XXXX'; 
0

这似乎是一个疯狂的事情 - 搜索可能会完全杀死你的服务器。也就是说,如果这是一次性/偶然使用手动运行的类型,那么您可以创建一个脚本来生成所需的SQL命令,然后执行结果集。我之前完成了这种事情来重构数据库中的列。 你的脚本将需要先运行一个查询来获取你的SQL服务器实例中的所有数据块的名称

SELECT * FROM sys.databases 

然后创建动态sql包括USE命令指定数据库,并使用INFORMATION_SCHEMA.TABLES和.columns以获取所有表格和列的名称,然后选择要搜索的列(例如,您是如何决定选择要搜索的列的,例如,只是列N'%name%')。

Then在for循环中使用这些信息来创建单独的表/列搜索。为了提高效率(并且如果它不工作,以帮助您调试)我建议使用@table变量。

最后,选择持有您创建的表查询的任何@tables的内容。

然后,可以在服务器上运行此输出 - 前提是您已将使用命令或带有前缀的表名与[dbname]。[schema]一起使用。

0

你可以使用这个存储过程

CREATE PROCEDURE dbo.SearchAllDatabases 
    @SearchTerm NVARCHAR(255) = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 

    IF @SearchTerm IS NULL OR @SearchTerm NOT LIKE N'%[^%^_]%' 
    BEGIN 
    RAISERROR(N'Please enter a valid search term.', 11, 1); 
    RETURN; 
    END 

    CREATE TABLE #results 
    (
    [database] SYSNAME, 
    [schema]  SYSNAME, 
    [table]  SYSNAME, 
    [column]  SYSNAME, 
    ExampleValue NVARCHAR(1000) 
); 

    DECLARE 
    @DatabaseCommands NVARCHAR(MAX) = N'', 
    @ColumnCommands NVARCHAR(MAX) = N''; 

    SELECT @DatabaseCommands = @DatabaseCommands + N' 
    EXEC ' + QUOTENAME(name) + '.sys.sp_executesql 
     @ColumnCommands, N''@SearchTerm NVARCHAR(MAX)'', @SearchTerm;' 
    FROM sys.databases 
    WHERE database_id > 4 -- non-system databases 
     AND [state]  = 0 -- online 
     AND user_access = 0; -- multi-user 

    SET @ColumnCommands = N'DECLARE @q NCHAR(1), 
      @SearchCommands NVARCHAR(MAX); 

    SELECT @q = NCHAR(39), 
     @SearchCommands = N''DECLARE @VSearchTerm VARCHAR(255) = @SearchTerm;''; 

    SELECT @SearchCommands = @SearchCommands + CHAR(10) + N'' 

     SELECT TOP (1) 
     [db]  = DB_NAME(), 
     [schema] = N'' + @q + s.name + @q + '', 
     [table] = N'' + @q + t.name + @q + '', 
     [column] = N'' + @q + c.name + @q + '', 
     ExampleValue = LEFT('' + QUOTENAME(c.name) + '', 1000) 
     FROM '' + QUOTENAME(s.name) + ''.'' + QUOTENAME(t.name) + '' 
     WHERE '' + QUOTENAME(c.name) + N'' LIKE @'' + CASE 
     WHEN c.system_type_id IN (35, 167, 175) THEN ''V'' 
     ELSE '''' END + ''SearchTerm;'' 

    FROM sys.schemas AS s 
    INNER JOIN sys.tables AS t 
    ON s.[schema_id] = t.[schema_id] 
    INNER JOIN sys.columns AS c 
    ON t.[object_id] = c.[object_id] 
    WHERE c.system_type_id IN (35, 99, 167, 175, 231, 239) 
     AND c.max_length >= LEN(@SearchTerm); 

    PRINT @SearchCommands; 
    EXEC sys.sp_executesql @SearchCommands, 
     N''@SearchTerm NVARCHAR(255)'', @SearchTerm;'; 

    INSERT #Results 
    (
    [database], 
    [schema], 
    [table], 
    [column], 
    ExampleValue 
) 
    EXEC [master].sys.sp_executesql @DatabaseCommands, 
    N'@ColumnCommands NVARCHAR(MAX), @SearchTerm NVARCHAR(255)', 
    @ColumnCommands, @SearchTerm; 

    SELECT [Searched for] = @SearchTerm; 

    SELECT [database],[schema],[table],[column],ExampleValue 
    FROM #Results 
    ORDER BY [database],[schema],[table],[column]; 
END 
GO 
+1

谢谢你,这工作正常:)。但是当你需要搜索一个子串时,你应该在它之前和之后使用%符号。这很酷,顺便说一句。 –

+1

好的,我会解决它的;) –