6

这是我到目前为止找到的所有超过 100 行的表:

SELECT sc.name +'.'+ ta.name TableName
 ,SUM(pa.rows) RowCnt
 FROM sys.tables ta
 INNER JOIN sys.partitions pa
 ON pa.OBJECT_ID = ta.OBJECT_ID
 INNER JOIN sys.schemas sc
 ON ta.schema_id = sc.schema_id
 WHERE ta.is_ms_shipped = 0 AND pa.index_id IN (1,0) AND pa.rows >100 
 GROUP BY sc.name,ta.name,pa.rows
 ORDER BY TABLENAME

是否有类似的东西我可以通过数据库查找表中列的特定行数据?

例如:其中 c.name = GUITARS 和 GUTARS = 'Fender'

编辑:我没有 CREATE PROCEDURE 权限或 CREATE TABLE

只是在某个列名下查找任何特定数据,如果它返回很多行并不重要。

4

3 回答 3

2

这是一个简单的存储过程,可以搜索 SQL Server 数据库表中的所有数据。如果表名是用逗号分隔的值指定的,这也可以在选定的表中进行搜索。它具有单独生成 SQL 而无需执行 SQL 的能力。附上它的脚本版本。

参数及用法:

@Tablenames -- 提供单个表名或多个表名,以逗号分隔。

如果留空,它将检查数据库中的所有表

@SearchStr -- 提供搜索字符串。使用“%”来创建搜索。

EX : X%--- 会给出以 X 开头的数据

%X--- 将给出以 X 结尾的数据

%X%--- 将给出包含 X 的数据

@GenerateSQLOnly -- 如果您只想生成 SQL 语句而不搜索数据库,请提供 1。

默认为 0,它会搜索。

    IF OBJECT_ID('SP_SearchTables','P') IS NOT NULL 
        DROP PROCEDURE SP_SearchTables 
    GO 
    CREATE PROCEDURE SP_SearchTables 
 @Tablenames VARCHAR(500) 
,@SearchStr NVARCHAR(60) 
,@GenerateSQLOnly Bit = 0 
AS 


    SET NOCOUNT ON 

    DECLARE @MatchFound BIT 

    SELECT @MatchFound = 0 

    DECLARE @CheckTableNames Table 
    ( 
    Tablename sysname 
    ) 

    DECLARE @SQLTbl TABLE 
    ( 
     Tablename        SYSNAME 
    ,WHEREClause    VARCHAR(MAX) 
    ,SQLStatement   VARCHAR(MAX) 
    ,Execstatus        BIT  
    ) 

    DECLARE @sql VARCHAR(MAX) 
    DECLARE @tmpTblname sysname 
    DECLARE @ErrMsg VARCHAR(100) 

    IF LTRIM(RTRIM(@Tablenames)) IN ('' ,'%') 
    BEGIN 

        INSERT INTO @CheckTableNames 
        SELECT Name 
          FROM sys.tables 
    END 
    ELSE 
    BEGIN 

        SELECT @sql = 'SELECT ''' + REPLACE(@Tablenames,',',''' UNION SELECT ''') + '''' 

        INSERT INTO @CheckTableNames 
        EXEC(@sql) 

    END 

    IF NOT EXISTS(SELECT 1 FROM @CheckTableNames) 
    BEGIN 

        SELECT @ErrMsg = 'No tables are found in this database ' + DB_NAME() + ' for the specified filter' 
        PRINT @ErrMsg 
        RETURN 

    END 

    INSERT INTO @SQLTbl 
    ( Tablename,WHEREClause) 
    SELECT QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME), 
            ( 
                SELECT '[' + SC.name + ']' + ' LIKE ''' + @SearchStr + ''' OR ' + CHAR(10) 
                  FROM SYS.columns SC 
                  JOIN SYS.types STy 
                    ON STy.system_type_id = SC.system_type_id 
                   AND STy.user_type_id =SC.user_type_id 
                 WHERE STY.name in ('varchar','char','nvarchar','nchar') 
                   AND SC.object_id = ST.object_id 
                 ORDER BY SC.name 
                FOR XML PATH('') 
            ) 
      FROM  SYS.tables ST 
      JOIN @CheckTableNames chktbls 
                ON chktbls.Tablename = ST.name  
      JOIN SYS.schemas SCh 
        ON ST.schema_id = SCh.schema_id 
     WHERE ST.name <> 'SearchTMP' 
      GROUP BY ST.object_id, QUOTENAME(SCh.name) + '.' +  QUOTENAME(ST.NAME) ; 


      UPDATE @SQLTbl 
         SET SQLStatement = 'SELECT * INTO SearchTMP FROM ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5) 

      DELETE FROM @SQLTbl 
       WHERE WHEREClause IS NULL 

    WHILE EXISTS (SELECT 1 FROM @SQLTbl WHERE ISNULL(Execstatus ,0) = 0) 
    BEGIN 

        SELECT TOP 1 @tmpTblname = Tablename , @sql = SQLStatement 
          FROM @SQLTbl  
         WHERE ISNULL(Execstatus ,0) = 0 

         IF @GenerateSQLOnly = 0 
         BEGIN 

            IF OBJECT_ID('SearchTMP','U') IS NOT NULL 
                DROP TABLE SearchTMP 
            EXEC (@SQL) 

            IF EXISTS(SELECT 1 FROM SearchTMP) 
            BEGIN 
                SELECT Tablename=@tmpTblname,* FROM SearchTMP 
                SELECT @MatchFound = 1 
              END 

         END 
         ELSE 
         BEGIN 
             PRINT REPLICATE('-',100) 
             PRINT @tmpTblname 
             PRINT REPLICATE('-',100) 
             PRINT replace(@sql,'INTO SearchTMP','') 
         END 

         UPDATE @SQLTbl 
            SET Execstatus = 1 
          WHERE Tablename = @tmpTblname 

    END 

    IF @MatchFound = 0  
    BEGIN 
        SELECT @ErrMsg = 'No Matches are found in this database ' + DB_NAME() + ' for the specified filter' 
        PRINT @ErrMsg 
        RETURN 
    END 

    SET NOCOUNT OFF 

go 

索纳·库马尔·穆图拉杰

我在工作中使用的一些非常灵活有用的代码。

如果您没有创建 procs 的权限,只需声明此脚本中使用的变量并将脚本作为临时查询执行

 DECLARE @Tablenames VARCHAR(500) = 'Table_Name' 
 DECLARE @SearchStr NVARCHAR(60) = 'Data_LookingFor' 
 DECLARE @GenerateSQLOnly Bit = 0 

你的 DBA 真的不相信你,他是不是 :) 无论如何,我已经稍微调整了代码,使用临时表而不是表变量,也许这对你有用:

DECLARE @Tablenames VARCHAR(500) = 'Table_name' 
DECLARE @SearchStr NVARCHAR(60) = 'Serach_String' 
DECLARE @GenerateSQLOnly Bit = 0 



    SET NOCOUNT ON 

    DECLARE @MatchFound BIT 

    SELECT @MatchFound = 0 

    IF OBJECT_ID('tempdb..#CheckTableNames') IS NOT NULL
    DROP TABLE #CheckTableNames

    CREATE Table #CheckTableNames  
    ( 
    Tablename sysname 
    ) 

    IF OBJECT_ID('tempdb..#SQLTbl') IS NOT NULL
    DROP TABLE #SQLTbl


    CREATE TABLE #SQLTbl 
    ( 
     Tablename        SYSNAME 
    ,WHEREClause    VARCHAR(MAX) 
    ,SQLStatement   VARCHAR(MAX) 
    ,Execstatus        BIT  
    ) 

    DECLARE @sql VARCHAR(MAX) 
    DECLARE @tmpTblname sysname 
    DECLARE @ErrMsg VARCHAR(100) 

    IF LTRIM(RTRIM(@Tablenames)) IN ('' ,'%') 
    BEGIN 

        INSERT INTO #CheckTableNames 
        SELECT Name 
          FROM sys.tables 
    END 
    ELSE 
    BEGIN 

        SELECT @sql = 'SELECT ''' + REPLACE(@Tablenames,',',''' UNION SELECT ''') + '''' 

        INSERT INTO #CheckTableNames 
        EXEC(@sql) 

    END 

    IF NOT EXISTS(SELECT 1 FROM #CheckTableNames) 
    BEGIN 

        SELECT @ErrMsg = 'No tables are found in this database ' + DB_NAME() + ' for the specified filter' 
        PRINT @ErrMsg 
        RETURN 

    END 

    INSERT INTO #SQLTbl 
    ( Tablename,WHEREClause) 
    SELECT QUOTENAME(SCh.name) + '.' + QUOTENAME(ST.NAME), 
            ( 
                SELECT '[' + SC.name + ']' + ' LIKE ''' + @SearchStr + ''' OR ' + CHAR(10) 
                  FROM SYS.columns SC 
                  JOIN SYS.types STy 
                    ON STy.system_type_id = SC.system_type_id 
                   AND STy.user_type_id =SC.user_type_id 
                 WHERE STY.name in ('varchar','char','nvarchar','nchar') 
                   AND SC.object_id = ST.object_id 
                 ORDER BY SC.name 
                FOR XML PATH('') 
            ) 
      FROM  SYS.tables ST 
      JOIN #CheckTableNames chktbls 
                ON chktbls.Tablename = ST.name  
      JOIN SYS.schemas SCh 
        ON ST.schema_id = SCh.schema_id 
     WHERE ST.name <> 'SearchTMP' 
      GROUP BY ST.object_id, QUOTENAME(SCh.name) + '.' +  QUOTENAME(ST.NAME) ; 


      UPDATE #SQLTbl 
         SET SQLStatement = 'SELECT * INTO SearchTMP FROM ' + Tablename + ' WHERE ' + substring(WHEREClause,1,len(WHEREClause)-5) 

      DELETE FROM #SQLTbl 
       WHERE WHEREClause IS NULL 

    WHILE EXISTS (SELECT 1 FROM #SQLTbl WHERE ISNULL(Execstatus ,0) = 0) 
    BEGIN 

        SELECT TOP 1 @tmpTblname = Tablename , @sql = SQLStatement 
          FROM #SQLTbl  
         WHERE ISNULL(Execstatus ,0) = 0 

         IF @GenerateSQLOnly = 0 
         BEGIN 

            IF OBJECT_ID('SearchTMP','U') IS NOT NULL 
                DROP TABLE SearchTMP 
            EXEC (@SQL) 

            IF EXISTS(SELECT 1 FROM SearchTMP) 
            BEGIN 
                SELECT Tablename = @tmpTblname,* FROM SearchTMP 
                SELECT @MatchFound = 1 
              END 

         END 
         ELSE 
         BEGIN 
             PRINT REPLICATE('-',100) 
             PRINT @tmpTblname 
             PRINT REPLICATE('-',100) 
             PRINT replace(@sql,'INTO SearchTMP','') 
         END 

         UPDATE #SQLTbl 
            SET Execstatus = 1 
          WHERE Tablename = @tmpTblname 

    END 

    IF @MatchFound = 0  
    BEGIN 
        SELECT @ErrMsg = 'No Matches are found in this database ' + DB_NAME() + ' for the specified filter' 
        PRINT @ErrMsg 
        RETURN 
    END 
于 2013-10-09T17:51:04.587 回答
2

我不知道我的解决方案是否适合您。但不是那样,我会使用下面的查询来获取所有可能的表,其中包含任何组合的吉他。

Select t.name, c.name from sys.columns c inner join sys.tables t on c.object_id=t.object_id Where c.name like '%guitar%'

假设它会根据表的数量和吉他柱的使用情况给出 20-25 个表。您可以看到结果集,并且几乎可以知道您的可用表。现在在您的猜测项目列表中搜索 Fenders。

我是这么说的,因为我正在维护一个 erp 应用程序,它有 6000 多个表和 13000 多个程序。因此,每当我需要找出相关表时,我只需使用相同的技巧就可以了。

于 2013-10-09T17:38:11.073 回答
1

请参阅我对如何在 SQL Server 数据库中的任何位置找到值的回答?我提供了一个脚本来搜索数据库中的所有表。

对此的伪代码描述是select * from * where any like 'foo'

它还允许您使用标准like语法搜索特定的列名,例如%guitar%搜索包含单词“guitar”的列名。

它运行即席,因此您不必创建存储过程,但您确实需要访问 information_schema。

在我的数据库开发工作中,我几乎每天都在 SQL 2000 和更高版本中使用这个脚本。

于 2013-10-09T18:37:43.507 回答