select all databases in sysobjects that have a table named 'mytable' regardless of schema?

时间秒杀一切 提交于 2019-12-24 12:47:37

问题


For a given sql 2000 - 2008 server I want to find any table named dbo.[MyTable] on that server. In addition, how do I find all databases that have a table named [dbo].[MyTable] and [AnySchemaName].[MyTable]. Is there a simple sp_ command like spTables MyTable? Or 'sp_AllDatabaseTable [MyTable]'?

I want to print it out like:

ServerName  Database  SchemaName  MyTable   Date Created
----------- --------- ----------- --------- -------------

Thx


回答1:


Of course, you can use sp_msforeachdb for this purpose but you need to remember that fhis function is neither documented nor officially supported. Also, sometimes it breaks. More about it here Making a more reliable and flexible sp_MSforeachdb

You can use this script to search table by name in all databases. I took it from Find table in every database of SQL server

DECLARE @TableName VARCHAR(256)
SET @TableName='YOUR_TABLE_NAME'
DECLARE @DBName VARCHAR(256)
DECLARE @varSQL VARCHAR(512)
DECLARE @getDBName CURSOR
SET @getDBName = CURSOR FOR
SELECT name
FROM sys.databases
CREATE TABLE #TmpTable (DBName VARCHAR(256),
SchemaName VARCHAR(256),
TableName VARCHAR(256),
create_date date, modify_date date)
OPEN @getDBName
FETCH NEXT
FROM @getDBName INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @varSQL = 'USE ' + @DBName + ';
INSERT INTO #TmpTable
SELECT '''+ @DBName + ''' AS DBName,
SCHEMA_NAME(schema_id) AS SchemaName,
name AS TableName,
create_date, modify_date
FROM sys.tables
WHERE name LIKE ''%' + @TableName + '%''' --WHERE name = '' + @TableName + ''' /* if you want to search by exact table name*/ 
EXEC (@varSQL)
FETCH NEXT
FROM @getDBName INTO @DBName
END
CLOSE @getDBName
DEALLOCATE @getDBName
SELECT *
FROM #TmpTable
DROP TABLE #TmpTable

Also, you may want to read this Find table name in all objects of all databases




回答2:


I really would prefer a solution that does not use either CURSORS nor sp_msforeachdb.

The solution below is gives you an idea, and you can adapt it to your own needs.

USE [master]
GO


SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


BEGIN TRY



SET NOCOUNT ON
SET DATEFORMAT DMY
SET DEADLOCK_PRIORITY NORMAL;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

DECLARE  @log NVARCHAR(MAX)
        ,@vCrlf CHAR(2);

SELECT  @log = ''
       ,@vCrlf = CHAR(13)+CHAR(10);


DECLARE @SQL NVARCHAR(MAX)

BEGIN TRY DROP TABLE #OBJECTS END TRY BEGIN CATCH END CATCH
CREATE TABLE #OBJECTS(
DB_ID INT,
OBJECT_ID INT,
S_NAME SYSNAME,
NAME SYSNAME,
ROW_COUNT INT,
STATISTICS_UPDATED DATETIME)




SELECT @SQL = '

SELECT db_id=db_id(),
       o.object_id,
       s_name=s.name,
       o.name,
       ddps.row_count 
       ,[Statistics_Updated]=STATS_DATE(I.OBJECT_ID,I.INDEX_ID)
FROM sys.indexes AS i
  INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_ID
  INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
  INNER JOIN sys.dm_db_partition_stats AS ddps ON i.OBJECT_ID = ddps.OBJECT_ID
  AND i.index_id = ddps.index_id 
WHERE i.index_id < 2  
 AND o.is_ms_shipped = 0

 '


set @SQL = (
            SELECT STUFF(
  (SELECT N'  ' + ' USE ' + QUOTENAME(name) +';' + @vCrlf + @SQL + @vCrlf    
                                FROM SYS.DATABASES SD
                                WHERE SD.STATE_DESC = 'ONLINE' -->Skips the database if it is not online
                                  AND SD.COMPATIBILITY_LEVEL > 80  
                                  AND SD.database_id > 3 -- NO MASTER NOR TEMPDB NOR MODEL
                        FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'')
)






INSERT INTO #OBJECTS
(   [db_id],
    [object_id],
    [s_name],
    [name],
    [row_count],
    [Statistics_Updated]
)
EXECUTE MASTER.DBO.sp_executesql @SQL

SELECT * FROM #OBJECTS
--WHERE NAME = 'THE NAME THAT I AM LOOKING FOR'

END TRY
BEGIN CATCH

        PRINT '--EXCEPTION WAS CAUGHT--' + CHAR(13) +
              'THE ERROR NUMBER:' + COALESCE(CAST ( ERROR_NUMBER()  AS VARCHAR), 'NO INFO') + CHAR(13) 

        PRINT 'SEVERITY: '        + COALESCE(CAST ( ERROR_SEVERITY()  AS VARCHAR), 'NO INFO') + CHAR(13) +
              'STATE: '           + COALESCE(CAST ( ERROR_STATE() AS VARCHAR), 'NO INFO')  + CHAR(13) 

        PRINT 'PROCEDURE: '       + COALESCE(CAST ( COALESCE(ERROR_PROCEDURE(),'NO INFO')  AS VARCHAR), 'NO INFO') + CHAR(13) +
              'LINE NUMBER: '     + COALESCE(CAST ( ERROR_LINE() AS VARCHAR), 'NO INFO')  + CHAR(13) 

        PRINT 'ERROR MESSAGE: '
        PRINT  CAST ( COALESCE(ERROR_MESSAGE(),'NO INFO')   AS NTEXT)

END CATCH;



回答3:


I prefer a set based approach:

Declare @TableName as Varchar(255)
Set @TableName = '<MyTableName>'

Declare @SQL as Varchar(max)
Select @SQL = Coalesce(@SQL + '
', '') + 
CASE 
WHEN Row_Number() Over (Order by Database_ID) = 1 
THEN '' 
ELSE 
'UNION ALL ' 
END +
'SELECT 
  ''' + d.Name + '''    as DatabaseName
, s.Name                as SchemaName 
, o.Name                as TableName 
FROM ' + d.Name +'.Sys.Objects o 
INNER JOIN ' + d.Name + '.Sys.Schemas s
ON o.Schema_ID = s.Schema_ID
WHERE o.Name like ''' + @TableName + ''''
FROM sys.databases d
where d.Name not like 'ReportServer%'
and d.Name not like 'SSISPackageRegistry'

Print @SQL 
EXEC(@SQL)



回答4:


I'd have said

sp_msforeachdb 'Select * from Sysobjects where name=''MyTable'''

But you don't need to, sysobjects is in the master table and does it for all databases anyway.

You should be able find the other columns easily enough.



来源:https://stackoverflow.com/questions/8363430/select-all-databases-in-sysobjects-that-have-a-table-named-mytable-regardless

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!