Display all the names of databases containing particular table - sql

I have many databases in my SQL Server.
I have to just search for database names containg particular table name Heartbitmaster
I have many databases such as Gotgold, DVD, etc and I just want to find database names from query that contain this table Heartbitmaster.
I searched I tried for query:
SELECT
TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_TYPE = 'base table'
AND table_schema = 'Heartbitmaster'
but it didn't work.
I searched further and came across:
SELECT name, database_id, create_date
FROM sys.databases
but dont know how to arrange further where condition for search of table name
Please help me.

I got it done through following query:
SELECT name
FROM sys.databases
WHERE CASE WHEN state_desc = 'ONLINE'
THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[heartbit]', 'U')
END IS NOT NULL

sp_MSforeachdb 'SELECT "?" AS DB, * FROM [?].sys.tables WHERE name like ''%tablename%'''
try this one

I needed something slightly different.
This will return all tables and their corresponding DBs with names containing the supplied string:
SELECT TABLE_NAME, TABLE_SCHEMA
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like '%_<insert_name_here>';

If you need to find database objects (e.g. tables, columns, triggers) by name - have a look at the FREE Red-Gate tool called SQL Search which does this - it searches your entire database for any kind of string(s).
It's a great must-have tool for any DBA or database developer - did I already mention it's absolutely FREE to use for any kind of use??
As for the INFORMATION_SCHEMA or the SQL Server specific catalog views: as far as I know, those are always constrained to the current database you're in - so you cannot search across all databases on your server. SQL Search does this for you - by searching into every single database on the server.

Create Procedure as bellow
CREATE PROCEDURE usp_FindTableNameInAllDatabase
#TableName VARCHAR(256)
AS
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))
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
FROM sys.tables
WHERE name LIKE ''%' + #TableName + '%'''
EXEC (#varSQL)
FETCH NEXT
FROM #getDBName INTO #DBName
END
CLOSE #getDBName
DEALLOCATE #getDBName
SELECT *
FROM #TmpTable
DROP TABLE #TmpTable
GO
EXEC usp_FindTableNameInAllDatabase 'Address'
GO
exec usp_FindTableNameInAllDatabase 'user'

It Works!!!!!!!
Run this query for finding database name for a particular table
The paste table name in #tablename
Drop table #tempo for next time run
declare #tablename varchar(max) = 'patient'
declare #count int = (select max(database_id) FROM sys.databases)
declare #n int = 1
declare #dbname varchar(max)
declare #query nvarchar(max)
create table #tempo(Databasename varchar(max), tablename varchar(max))
while #n <= #count
begin
select #dbname = name from sys.databases where database_id = #n and service_broker_guid <> '00000000-0000-0000-0000-000000000000'
set #query = 'insert into #tempo(Databasename,tablename) select '''+#dbname+''' [Database],name from '+#dbname+'.sys.tables where name like ''%'+#tablename+'%'''
exec(#query)
set #n=#n+1;
end
select * from #tempo
At the last giving error like
Database 'databasename' cannot be opened because it is offline.
then run this query separately
select * from #tempo

I Complete sp_MSforeachdb and create a procedure like this :
create PROCEDURE findTableName
#tablename nvarchar(max)
AS
BEGIN
declare #sqlCommand nvarchar(max)
CREATE TABLE #t (DBName VARCHAR(256),SchemaName VARCHAR(256),TableName VARCHAR(256))
set #sqlCommand='insert into #t (DBName,SchemaName,TableName) exec sp_MSforeachdb ''SELECT "?" AS DB, SCHEMA_NAME(schema_id) AS SchemaName ,name FROM [?].sys.tables WHERE name like ''''%'+#tablename+'%'''''''
--print #sqlCommand
exec ( #sqlCommand)
select * from #t
END

Related

SQL Server look for stored procedure

I'm using SQL Server Management Studio and I have multiple server connections and I need to know where a specific stored procedure exists in every server which contains multiple databases!
Looking for a query to run on each server
Here is a little script that you could run on each server.
I know that it uses a while loop, which is generally not preferred, someone might be able to improve on it.
Run the script from the master database.
SQL Query:
set nocount on
declare #procname varchar(150) = '<SPROCNAME_TO_FIND>' -- SET THIS TO THE STORED PROCEDURE NAME YOU ARE LOOKING FOR
declare #alldbonserver table
( databasename varchar(150),
doneflag bit )
declare #foundtbl table
( countcol int,
dbname varchar(150) )
declare #errortbl table
( dbname varchar(150) )
insert #alldbonserver
( databasename,
doneflag )
select sdb.name,
0
from sys.databases sdb
declare #curdbname varchar(150),
#sqlcmd varchar(max)
while exists (select 1
from #alldbonserver
where doneflag = 0)
begin
select top 1
#curdbname = databasename
from #alldbonserver
where doneflag = 0
select #sqlcmd = 'select distinct 1, ''' + #curdbname + ''' as dbname from ' + #curdbname + '.sys.objects where type = ''P'' and name = ''' + #procname + ''''
begin try
insert #foundtbl
( countcol, dbname )
exec(#sqlcmd)
end try
begin catch
insert #errortbl
values ( #curdbname )
end catch
update #alldbonserver
set doneflag = 1
where databasename = #curdbname
end
select dbname as 'Databases with stored procedure'
from #foundtbl
select dbname as 'Unable to access databases'
from #errortbl
set nocount off
Sample output:
Databases with stored procedure
-----------------------------------------
MainDatabase
SomeOtherDatabase
Unable to access databases
-----------------------------------------
model
ReportServer$SQLTemp
VeryPrivateDatabase
If you are using SSMS, you could create a server registration group that contains all of the servers you connect to, right click on the group and run this query against the group: exec sp_MSforeachdb 'select * from [?].sys.procedures where name=''<your_name_here>'''
This query will enumerate each of the databases on each of the servers in the group (note: the single quotes are like that for a reason...)
I just put this together on SQL2012. It should return all Stored Procs on a Server for a given name. If you leave #SPName blank, you will get all of them.
The Query utilizes sys.all_objects so you could easily change it to work the same for tables, functions, any or all db objects.
DECLARE #SPName VARCHAR(256)
SET #SPName = 'My_SP_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),
SPName VARCHAR(256))
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 SPName
FROM sys.all_objects
WHERE [type] = ''P'' AND name LIKE ''%' + #SPName + '%'''
EXEC (#varSQL)
FETCH NEXT
FROM #getDBName INTO #DBName
END
CLOSE #getDBName
DEALLOCATE #getDBName
SELECT *
FROM #TmpTable
DROP TABLE #TmpTable

USE DATABASE_NAME doesn't change the database when used in dynamic SQL

I am able to retrieve for a single database using the below query
Select Table_catalog[Instance Name],
Table_name[Database Table],
Column_name[Column],
Data_type[Column Type]
FROM information_schema.columns
where Data_type in ('varchar')
Order by Table_name,Data_type
but I wanted to list it for all available databases in the server
Declare #I int =1,#Qry nVarchar(1000),#DatabaseName nvarchar(100)
Declare #TempTable Table
(
Sno Int Identity(1,1),
DatabaseName Varchar(100)
)
Insert into #TempTable
Select name
from sys.databases
where database_id>4
Select * from #TempTable
While(#i<=(Select max(sno) from #TempTable))
Begin
Select #DatabaseName=DatabaseName from #TempTable where sno=#i
Select #DatabaseName
set #Qry='Use '+ #DatabaseName
**exec sp_executesql #Qry**
set #Qry= '
Select Table_catalog[Instance Name],
Table_name[Database Table],
Column_name[Column],
Data_type[Column Type]
FROM information_schema.columns
where Data_type in (''datetime'',''date'',''time'',''smalldatetime'')
Order by Table_name,Data_type'
exec sp_executesql #Qry
Set #i=#i+1
End
Its not working since the use databasename is not actually changing the database and repeat the result set of the database currently in use .. any suggestions on this,
Dynamic SQL always executes in its own scope, so your USE statement has no effect on the second dynamic query.
This should work for you (your loop is unnecessary and awkward):
declare #Database sysname, #sql nvarchar(max)
declare Databases cursor local fast_forward
for select name from sys.databases where database_id > 4
open Databases
fetch next from Databases into #Database
while ##fetch_status = 0
begin
set #sql = 'Select
Table_catalog [Instance Name],
Table_name [Database Table],
Column_name [Column],
Data_type [Column Type]
FROM
' + quotename(#Database) + '.information_schema.columns
where
Data_type in (''datetime'',''date'',''time'',''smalldatetime'')
Order by
Table_name,
Data_type'
exec sp_executesql #sql
fetch next from Databases into #Database
end
close Databases
deallocate Databases
You can use for this task the undocumented procedure sp_MSforeachdb. Just tested on my enviroment at it works flawlessly.
EDIT
As Pondlife pointed out, the database part was missing on the three part name syntax. Added and now is correctly working. Also added a WHERE clause to avoid searching on unnecessary databases as master, msdb, tempdb and model.
EXEC sp_MSforeachdb
'SELECT Table_catalog[Instance Name],
Table_name[Database Table],
Column_name[Column],
Data_type[Column Type]
FROM ?.information_schema.columns
WHERE Data_type in (''varchar'')
AND ''?'' NOT IN (''master'',''msdb'',''tempdb'',''model'')
ORDER BY Table_name,Data_type'
Just in case you want to know more about this undocumented procedure check here and here. Remember that undocumented means that officially Microsoft does not support this procedure and therefore it could change without notice.
Sample result from AdventureWorks2008R2 database:
Instance Name Database Table Column Column Type
AdventureWorks2008R2 Customer AccountNumber varchar
AdventureWorks2008R2 Password PasswordHash varchar
AdventureWorks2008R2 Password PasswordSalt varchar
AdventureWorks2008R2 SalesOrderHeader CreditCardApprovalCode varchar
Thanks #pondlife as per your suggestion i could make small changes( pass the database name from outside the scope of dynamic query) and the query returns the result instead cursors i have used while loop
Declare #I int =1,#Qry nVarchar(1000),#DatabaseName nvarchar(100)
Declare #TempTable Table
(
Sno Int Identity(1,1),
DatabaseName Varchar(100)
)
Insert into #TempTable
Select name
from sys.databases
where database_id>4
Select * from #TempTable
While(#i<=(Select max(sno) from #TempTable))
Begin
Select #DatabaseName=DatabaseName from #TempTable where sno=#i
Select #DatabaseName
--set #Qry='Use '+ #DatabaseName
-- exec sp_executesql #Qry**
set #Qry= '
Select Table_catalog[Instance Name],
Table_name[Database Table],
Column_name[Column],
Data_type[Column Type]
FROM'+quotename(#DatabaseName)+ '. information_schema.columns
where Data_type in (''datetime'',''date'',''time'',''smalldatetime'')
Order by Table_name,Data_type'
exec sp_executesql #Qry
Set #i=#i+1
End

Find database location of a table

I have several databases in my SQL Server 2008. And I forgot where some tables from, so I need to ask if there's a such query that finds the database location of a certain table?
I need something goes like this:
SELECT DATABASE_NAME FROM SQLSERVER WHERE TABLE= "TBL_PRODUCTS"
Addition:
Now, i need to know the database location of certain Views and Stored Procedures
Something like this:
SELECT DATABASE_NAME FROM SQLSERVER WHERE VIEW= "VW_PRODUCTS"
SELECT DATABASE_NAME FROM SQLSERVER WHERE StoredProcedure= "SP_PRODUCTS"
Thanks!
The following procedure will do the job:
CREATE PROCEDURE usp_FindTableNameInAllDatabase
#TableName VARCHAR(256)
AS
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))
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
FROM sys.tables
WHERE name LIKE ''%' + #TableName + '%'''
EXEC (#varSQL)
FETCH NEXT
FROM #getDBName INTO #DBName
END
CLOSE #getDBName
DEALLOCATE #getDBName
SELECT *
FROM #TmpTable
DROP TABLE #TmpTable
GO
EXEC usp_FindTableNameInAllDatabase 'Address'
GO
The result would look like that:
Source
Do this
Use Master
Go
select
'select '''+CAST(name as varchar(200))+''' from '+CAST(name as varchar(200))+'.sys.tables where name = yourTableName'
from sysdatabases
replacing yourTableName with the name of your table, with ' '
You will get selects; then run those and will get the results.
If there are more than 100 databases, use results to text, because to grid, you will only get 100 selects maximum

Sql Server 2008 - How to query for status of fulltext catalogs on all user databases?

I have several databases in a Sql Server 2008 R2 instance. Some of those databases have a full-text enabled table. The name of the full-text table is equal for all databases, but the databases have different names and they are created on demand (I never know what databases exists and what does not).
The thing is: I need to query all catalogs in all databases to check if a population is done, but I have no idea how many databases I have (of course I know, but they are created on demand as I said). The script must query all databases and check if a population is done in a table (which the name I know because it never changes besides the name of the database that does change)
I have seen many people using things like:
sys.fulltext_catalogs
But it does not work if i am using the master database for example.
Any ideas?
Edit: Here is more complete code with a cursor, a full list of databases (even those without catalogs), and the right catalog view name:
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += ' UNION ALL
SELECT [name] = ''' + QUOTENAME(name) + ''',
catalog_name = name COLLATE Latin1_General_CI_AI,
is_importing
FROM ' + QUOTENAME(name) + '.sys.fulltext_catalogs'
FROM sys.databases WHERE database_id > 4;
SET #sql = 'SELECT [database] = d.name,
s.catalog_name,
s.is_importing
FROM sys.databases AS d
LEFT OUTER JOIN (' + STUFF(#sql, 1, 10, '') + ') AS s
ON QUOTENAME(d.name) = s.name
WHERE d.database_id > 4;';
CREATE TABLE #temp(db SYSNAME, catalog_name NVARCHAR(255), is_importing BIT);
INSERT #temp EXEC sp_executesql #sql;
DECLARE #db SYSNAME, #catalog_name NVARCHAR(255), #is_importing BIT;
DECLARE c CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR SELECT db, catalog_name, is_importing FROM #temp;
OPEN c;
FETCH NEXT FROM c INTO #db, #catalog_name, #is_importing;
WHILE ##FETCH_STATUS = 0
BEGIN
IF #catalog_name IS NULL
BEGIN
PRINT 'No catalogs for ' + #db;
END
ELSE
BEGIN
IF #is_importing = 1
BEGIN
PRINT 'Do something to ' + #db
+ '(importing)';
END
ELSE
BEGIN
PRINT #db + ' is not importing.';
END
END
FETCH NEXT FROM c INTO #db, #catalog_name, #is_importing;
END
CLOSE c;
DEALLOCATE c;
DROP TABLE #temp;
This gives you a complete list of used catalogs.
CREATE TABLE #info (
databasename VARCHAR(128)
, [Fulltext Catalog Name] VARCHAR(128));
SET NOCOUNT ON;
INSERT INTO #info
EXEC sp_MSforeachdb 'use ?
SELECT ''?''
, name
FROM sys.fulltext_catalogs;'
SELECT * FROM #info
-- get rid of temp table
DROP TABLE #info;

How do I identify views with broken dependencies in SQL Server?

We have a large number of views in an inherited database which some of them are missing dependencies (table or even other views)?
What's the best way to identify the views which have missing dependencies?
DECLARE #stmt nvarchar(max) = ''
DECLARE #vw_schema NVARCHAR(255)
DECLARE #vw_name varchar(255)
IF OBJECT_ID('tempdb..#badViews') IS NOT NULL DROP TABLE #badViews
IF OBJECT_ID('tempdb..#nulldata') IS NOT NULL DROP TABLE #nulldata
CREATE TABLE #badViews
(
[schema] NVARCHAR(255),
name VARCHAR(255),
error NVARCHAR(MAX)
)
CREATE TABLE #nullData
(
null_data varchar(1)
)
DECLARE tbl_cursor CURSOR LOCAL FORWARD_ONLY READ_ONLY
FOR SELECT name, SCHEMA_NAME(schema_id) AS [schema]
FROM sys.objects
WHERE type='v'
OPEN tbl_cursor
FETCH NEXT FROM tbl_cursor
INTO #vw_name, #vw_schema
WHILE ##FETCH_STATUS = 0
BEGIN
SET #stmt = 'SELECT TOP 1 * FROM [' + #vw_schema + N'].[' + #vw_name + ']'
BEGIN TRY
INSERT INTO #nullData EXECUTE sp_executesql #stmt
END TRY
BEGIN CATCH
IF ERROR_NUMBER() != 213 BEGIN
INSERT INTO #badViews (name, [schema], error) values (#vw_name, #vw_schema, ERROR_MESSAGE())
END
END CATCH
FETCH NEXT FROM tbl_cursor
INTO #vw_name, #vw_schema
END
CLOSE tbl_cursor -- free the memory
DEALLOCATE tbl_cursor
SELECT * FROM #badViews
DROP TABLE #badViews
DROP TABLE #nullData
Update 2017
Updated the answer as per #robyaw's answer.
I've also fixed a bug in it for the computed values in the select statements. It seems SELECT TOP 1 NULL from vwTest doesn't throw an error when vwTest contains a column like let's say 1/0 as [Col1], but SELECT TOP 1 * from vwTest it does throw an exception.
Update 2018
Fix false positives for views and or schema that contain special characters in their name. Thanks to #LucasAyala
Adrian Iftode's solution is good, but fails if there are views that are not associated with the default schema. The following is a revised version of his solution that takes schema into account, whilst also providing error information against each failing view (tested on SQL Server 2012):
DECLARE #stmt NVARCHAR(MAX) = '';
DECLARE #vw_schema NVARCHAR(255);
DECLARE #vw_name NVARCHAR(255);
CREATE TABLE #badViews
(
[schema] NVARCHAR(255)
, name NVARCHAR(255)
, error NVARCHAR(MAX)
);
CREATE TABLE #nullData
(
null_data VARCHAR(1)
);
DECLARE tbl_cursor CURSOR FORWARD_ONLY READ_ONLY
FOR
SELECT
SCHEMA_NAME(schema_id) AS [schema]
, name
FROM
sys.objects
WHERE
[type] = 'v';
OPEN tbl_cursor;
FETCH NEXT FROM tbl_cursor INTO #vw_schema, #vw_name;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #stmt = CONCAT(N'SELECT TOP 1 NULL FROM ', #vw_schema, N'.', #vw_name);
BEGIN TRY
-- silently execute the "select from view" query
INSERT INTO #nullData EXECUTE sp_executesql #stmt;
END TRY
BEGIN CATCH
INSERT INTO #badViews ([schema], name, error)
VALUES (#vw_schema, #vw_name, ERROR_MESSAGE());
END CATCH
FETCH NEXT FROM tbl_cursor INTO #vw_schema, #vw_name;
END
CLOSE tbl_cursor;
DEALLOCATE tbl_cursor;
-- print the views with errors when executed
SELECT * FROM #badViews;
DROP TABLE #badViews;
DROP TABLE #nullData;
Try this
Call sp_refreshsqlmodule on all non-schema bound stored procedures:
DECLARE #template AS varchar(max)
SET #template = 'PRINT ''{OBJECT_NAME}''
EXEC sp_refreshsqlmodule ''{OBJECT_NAME}''
'
DECLARE #sql AS varchar(max)
SELECT #sql = ISNULL(#sql, '') + REPLACE(#template, '{OBJECT_NAME}',
QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME))
FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
EXEC (
#sql
)
This works for all views, functions and SPs. Schemabound objects won't have problems and this can't be run on them, that's why they are excluded.
Note that it is still possible for SPs to fail at runtime due to missing tables - this is equivalent to attempting to ALTER the procedure.
Note also that just like ALTER, it will lose extended properties on UDFs - I script these off and restore them afterwards.
If you're using SQL Server 2005 or 2008, you could import the project in to Visual Studio 2008 or 2010 and analyze broken dependencies from the Visual Studio project
I would backup the database, restore it on my dev machine, create a script with all the views in a new window in management server, drop all views and try executing the script. Whenever a view is "corrupt", the execution will fail with an error message, e.g. Not existing table or column.