6

This is what I have so far to find all tables with more than 100 rows:

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

Is there something similar where I can go through the database to find out a specific row data for a column within a table?

For example: Where c.name = GUITARS and GUTARS = 'Fender'

Edit: I do not have CREATE PROCEDURE permission OR CREATE TABLE

Just looking for any specific data under a certain column name, doesn't matter if it returns a lot of rows.

Sewder
  • 754
  • 3
  • 11
  • 37

3 Answers3

2

I dont know whether my solutions works for you or not. But instead of that i would use the query below to get all possible tables having guitar in any combination .

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%'

Suppose it will give 20-25 tables depending on the no of tables and usage of guitar columns. You can see the resultset and can almost know your usable tables. Now search for Fenders in your guessed items list.

I am saying so as I am working on maintenance of an erp app and it has 6000+ tables and 13000+ procedures. So whenever I need to find out the related tables , i just use the same trick and it works.

  • This is what I've been doing, just wanted something that would do it automatically for me. I did find some important columns this way though! – Sewder Oct 09 '13 at 18:08
2

This is a simple stored procedure which can search through all the data in the SQL Server database tables. Also this has capability to search in the selected tables if the table names are specified with comma separated values. This has a capability to generate the SQL alone without executing the SQL. Enclosing the script version of it also.

Parameters and usage:

@Tablenames -- Provide a single table name or multiple table name with comma separated.

If left blank, it will check for all the tables in the database

@SearchStr -- Provide the search string. Use the '%' to coin the search.

EX : X%--- will give data starting with X

%X--- will give data ending with X

%X%--- will give data containing X

@GenerateSQLOnly -- Provide 1 if you only want to generate the SQL statements without searching the database.

By default it is 0 and it will search.

    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 

By Sorna Kumar Muthuraj

Something I use at work really flexible useful piece of code.

If you don't have permissions to create procs just declare the variables being used in this script and execute script as ad-hoc query

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

Your DBA really doesn't trust you does he :) Anyway, I have tweaked the code a little bit more making use of temp table rather than the Table variables, maybe this will work for you:

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 
Rodia
  • 1,407
  • 8
  • 22
  • 29
M.Ali
  • 67,945
  • 13
  • 101
  • 127
  • I get an error saying: Msg 102, Level 15, State 1, Procedure SP_SearchTables, Line 171 Incorrect syntax near 'OFF'. – Sewder Oct 09 '13 at 18:07
  • Thanks Muhammed, this is really usefull Unfortunately I just realized I don't ahve CREATE PROCEDURE permissions for this data base. Is there a way I can do this without creating a Procedure. I should've probably mentioned this in the question. Editing Now. – Sewder Oct 09 '13 at 18:26
  • You can use the script without creating a proc Just Dont create a proc and Declare the variables being used in this code and Pass values something like this – M.Ali Oct 09 '13 at 18:38
  • Now I'm gettin a Create Table Permission Denied, Can I do this without Creating A new Table? – Sewder Oct 09 '13 at 19:23
  • @Sewder my script will do exactly that. – Tim Lehner Oct 09 '13 at 19:33
1

Please see my answer to How do I find a value anywhere in a SQL Server Database? where I provide a script to search all tables in a database.

A pseudo-code description of this would be be select * from * where any like 'foo'

It also allows you to search specific column names using standard like syntax, e.g. %guitar% to search column names that have the word "guitar" in them.

It runs ad-hoc, so you do not have to create a stored procedure, but you do need access to information_schema.

I use this script in SQL 2000 and up almost daily in my DB development work.

Community
  • 1
  • 1
Tim Lehner
  • 14,813
  • 4
  • 59
  • 76
  • I tried to run it but it took over 1 min so I had to cancel. I'm sure this works but there doesn't seem to be a practical use for me without slowing down the server too much. Appreciate it! – Sewder Oct 09 '13 at 19:50
  • 2
    You must have [a lot of guitars](http://www.imdb.com/title/tt0084503/quotes?item=qt0239707). – Tim Lehner Oct 09 '13 at 19:55