Select databases which only contain specific table - sql

I'm looking for a way to select all databases on my sql server, which only contain the table "dbo.mytable"
How can i do this ?
I already have these two sql queries :
Select name From sys.databases Where database_id > 5
And
IF EXISTS
(SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[mytable]') AND type in (N'U'))
Select 1 [Exists]
Else
Select 0 [Exists]
The first query, lists all databases on my sql server, and the second checks if dbo.mytable exists. I would like to merge them.
Thanks

A concise way that brings them all back in one resultset is
SELECT name
FROM sys.databases
WHERE CASE
WHEN state_desc = 'ONLINE'
THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[mytable]', 'U')
END IS NOT NULL

You can use sp_Msforeachdb that is an undocumented Stored procedure and run on all databases :
EXEC sp_Msforeachdb "use [?];select * from sys.tables where name='MYTable' "
more about sp_msforeachtable : The undocumented sp_MSforeachdb procedure

Return list of databases, which contains the specified table -
Query:
DECLARE
#SQL NVARCHAR(MAX)
, #table_name SYSNAME
SELECT #table_name = 'dbo.test'
IF OBJECT_ID('tempdb.dbo.#db_temp') IS NOT NULL
DROP TABLE #db_temp
CREATE TABLE #db_temp (db_nm SYSNAME)
SELECT #SQL = (
SELECT '
USE [' + d.name + '];
INSERT INTO #db_temp (db_nm)
SELECT DB_NAME()
WHERE EXISTS(
SELECT 1
FROM sys.objects
WHERE [object_id] = OBJECT_ID(''' + #table_name + ''')
AND [type] = ''U''
)'
FROM sys.databases d
WHERE d.name NOT IN ('master', 'tempdb', 'model', 'msdb')
AND d.state_desc != 'OFFLINE'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
EXEC sys.sp_executesql #SQL
SELECT *
FROM #db_temp dt
Output:
USE [...];
INSERT INTO #db_temp (db_nm)
SELECT DB_NAME()
WHERE EXISTS(
SELECT 1
FROM sys.objects
WHERE [object_id] = OBJECT_ID('...')
AND [type] = 'U'
)
...

Related

Inserting into production table from the latest archive table

I have a project where I need to insert into a production table the data that is in an archive table. The problem is that I have multiple archive tables for a specific table, all with a timestamp at the end of the table name. My idea was to find the latest archive table by doing this:
select top (1) table_name from INFORMATION_SCHEMA.tables where TABLE_CATALOG = 'databasename' and table_name like 'archive_User_%' order by table_name desc
This will give me the name of the last archive table for "User".
Question is, how to I write my insert into query to use this as the name of the table I want to insert into from?
Thanks!!!
how to I write my insert into query to use this as the name of the table I want to insert into from?
Dynamic SQL. EG:
declare #tn sysname
declare #schema sysname
select top (1) #tn = name , #schema = schema_name(schema_id)
from sys.tables
where name like 'archive_User_%'
order by name desc
declare #sql nvarchar(max) = concat( '
insert into sometable (a,b,c,d)
select a,b,c,d
from ',quotename(#schema),'.',quotename(#tn),';
')
--print #sql
exec sp_executesql #sql
Declare #QueryText nVarChar(max)
Select #QueryText = Concat('Insert Into ', QuoteName(s.name), '.', QuoteName(t.name), ' (',
STRING_AGG(c.name,', '), ')', Char(10), 'Select ', STRING_AGG(c.name,', '),
Char(10),'From ', QuoteName(t1.schemaName), '.', QuoteName(t1.tableName))
From sys.tables as t Inner Join sys.schemas as s On (t.schema_id=s.schema_id)
Inner Join sys.columns as c On (t.object_id=c.object_id)
,(Select Max(name) As tableName, schema_name(schema_id) as
schemaName From sys.tables Where name Like 'archive_User_%'
And schema_name(schema_id)='SchemaName' Group by
schema_name(schema_id)) As t1
Where t.name = 'TableName'
And s.name = 'SchemaName'
-- And c.name Not In ('ColumnName1','ColumnName2')
Group by s.name, t.name, t1.tableName, t1.schemaName
Execute sp_executesql #QueryText

How can I retrieve all the stored procedures and their input and output parameters in all the databases from SQL Server?

Apologies, for a convoluted question - I'm not a dba. Is there a simple script I can run that can list all the stored procedures I have on SQL Server, grouped by database and list them with the input and output parameters that go with the stored procedures.
I'm writing a similar script outside of SQL, to do the same for a language calling the stored procedures, so I find if there are conflicts in a legacy application.
Use the following script:
DECLARE #CurrentRowID INT
,#CurrentDatabase SYSNAME;
DECLARE #DynamicSQL NVARCHAR(MAX);
IF OBJECT_ID('tempdb..##DataSource') IS NOT NULL
BEGIN
DROP TABLE ##DataSource;
END;
CREATE TABLE ##DataSource
(
[database] SYSNAME
,[procedure] SYSNAME
,[parameter] SYSNAME
,[is_output] BIT
);
DECLARE #DataBases TABLE
(
[RowID] INT IDENTITY(1,1)
,[database] SYSNAME
);
INSERT INTO #DataBases ([database])
SELECT [name]
FROM [sys].[databases];
WHILE EXISTS(SELECT 1 FROM #DataBases)
BEGIN
SELECT TOP 1 #CurrentRowID = [RowID]
,#CurrentDatabase = [database]
FROM #DataBases;
SET #DynamicSQL = N'INSERT INTO ##DataSource
SELECT ''' + #CurrentDatabase + ''' AS [database]
,PR.[name]
,P.[name]
,P.[is_output]
FROM [' + #CurrentDatabase + '].[sys].[procedures] PR
INNER JOIN [' + #CurrentDatabase + '].[sys].[parameters] P
ON PR.[object_id] = P.[object_id]'
EXEC sp_executesql #DynamicSQL;
DELETE FROM #DataBases
WHERE [RowID] = #CurrentRowID;
END;
SELECT *
FROM ##DataSource
Of course, you can filter some of the databases, or add more columns from the sys.procedures dmv like system type for example.
Run a loop/cursor on sys.databases and inside the loop, USE and run the following query and keep taking union:
SELECT pr.name [Procedure], par.name Parameter, CASE WHEN is_output = 1 THEN 'Output Parameter' ELSE 'Input Parameter' END [ParameterType]
FROM sys.parameters par
INNER JOIN sys.procedures pr ON pr.object_id = par.object_id
ORDER BY [Procedure], [ParameterType]
This will give you all procedures and their dependent parameters.
declare #sql nvarchar(max) = ''
set #sql = #sql + N'union all
select '''+ quotename(d.name) + N''' as db, s.name as sname, p.name as p.name, r. name as paramname, r.is_output as paramoutput
from '''+ quotename(d.name) + N'''.sys.procedures p
join sys.parameters r on p.object_id = r.object_id
join sys.schemas s on p.schema_id = s.schema_id'
from sys.databases d
-- where d.name like ....
order by d.name
set #sql = stuff#sql, 1, 10, N'')
exec sp_executesql #sql
-- not tested

To view all the tables in a database server

Can anyone please help me with the query to list all the tables in all the databases in a single server?.
Thanks in advance.
Use sp_MSforeachdb to iterate through all databases and INFORMATION_SCHEMA.TABLES to query the tables in each:
sp_MSforeachdb 'USE [?]; SELECT * FROM INFORMATION_SCHEMA.TABLES'
AS stated here by
Try with dynamic query
You need a query for each database against sys.tables.
select 'master' as DatabaseName,
T.name collate database_default as TableName
from master.sys.tables as T
union all
select 'tempdb' as DatabaseName,
T.name collate database_default as TableName
from tempdb.sys.tables as T
union all
select 'model' as DatabaseName,
T.name collate database_default as TableName
from model.sys.tables as T
union all
select 'msdb' as DatabaseName,
T.name collate database_default as TableName
from msdb.sys.tables as T
You can use sys.databases to build and execute the query dynamically.
declare #SQL nvarchar(max)
set #SQL = (select 'union all
select '''+D.name+''' as DatabaseName,
T.name collate database_default as TableName
from '+quotename(D.name)+'.sys.tables as T
'
from sys.databases as D
for xml path(''), type).value('substring((./text())[1], 13)', 'nvarchar(max)')
--print #SQL
exec (#SQL)
IF OBJECT_ID('tempdb.dbo.#tbl') IS NOT NULL
DROP TABLE #tbl
CREATE TABLE #tbl (
database_id SYSNAME
, tbl_name SYSNAME
, sch_name SYSNAME
, [rows] INT
)
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = STUFF((
SELECT '
USE [' + d.name + ']
INSERT INTO #tbl
SELECT DB_NAME(), o.name, s.name, p.[rows]
FROM sys.objects o
JOIN sys.schemas s ON o.[schema_id] = s.[schema_id]
LEFT JOIN (
SELECT p.[object_id], [rows] = SUM(p.[rows])
FROM sys.partitions p
WHERE p.index_id < 2
GROUP BY p.[object_id]
) p ON p.[object_id] = o.[object_id]
WHERE o.[type] = ''U''
AND o.is_ms_shipped = 0;'
FROM sys.databases d
WHERE d.[state] = 0
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
EXEC sys.sp_executesql #SQL
SELECT * FROM #tbl

How to find column names for all tables in all databases in SQL Server

I want to find all column names in all tables in all databases. Is there a query that can do that for me?
Try this:
select
o.name,c.name
from sys.columns c
inner join sys.objects o on c.object_id=o.object_id
order by o.name,c.column_id
With resulting column names this would be:
select
o.name as [Table], c.name as [Column]
from sys.columns c
inner join sys.objects o on c.object_id=o.object_id
--where c.name = 'column you want to find'
order by o.name,c.name
Or for more detail:
SELECT
s.name as ColumnName
,sh.name+'.'+o.name AS ObjectName
,o.type_desc AS ObjectType
,CASE
WHEN t.name IN ('char','varchar') THEN t.name+'('+CASE WHEN s.max_length<0 then 'MAX' ELSE CONVERT(varchar(10),s.max_length) END+')'
WHEN t.name IN ('nvarchar','nchar') THEN t.name+'('+CASE WHEN s.max_length<0 then 'MAX' ELSE CONVERT(varchar(10),s.max_length/2) END+')'
WHEN t.name IN ('numeric') THEN t.name+'('+CONVERT(varchar(10),s.precision)+','+CONVERT(varchar(10),s.scale)+')'
ELSE t.name
END AS DataType
,CASE
WHEN s.is_nullable=1 THEN 'NULL'
ELSE 'NOT NULL'
END AS Nullable
,CASE
WHEN ic.column_id IS NULL THEN ''
ELSE ' identity('+ISNULL(CONVERT(varchar(10),ic.seed_value),'')+','+ISNULL(CONVERT(varchar(10),ic.increment_value),'')+')='+ISNULL(CONVERT(varchar(10),ic.last_value),'null')
END
+CASE
WHEN sc.column_id IS NULL THEN ''
ELSE ' computed('+ISNULL(sc.definition,'')+')'
END
+CASE
WHEN cc.object_id IS NULL THEN ''
ELSE ' check('+ISNULL(cc.definition,'')+')'
END
AS MiscInfo
FROM sys.columns s
INNER JOIN sys.types t ON s.system_type_id=t.user_type_id and t.is_user_defined=0
INNER JOIN sys.objects o ON s.object_id=o.object_id
INNER JOIN sys.schemas sh on o.schema_id=sh.schema_id
LEFT OUTER JOIN sys.identity_columns ic ON s.object_id=ic.object_id AND s.column_id=ic.column_id
LEFT OUTER JOIN sys.computed_columns sc ON s.object_id=sc.object_id AND s.column_id=sc.column_id
LEFT OUTER JOIN sys.check_constraints cc ON s.object_id=cc.parent_object_id AND s.column_id=cc.parent_column_id
ORDER BY sh.name+'.'+o.name,s.column_id
EDIT
Here is a basic example to get all columns in all databases:
DECLARE #SQL varchar(max)
SET #SQL=''
SELECT #SQL=#SQL+'UNION
select
'''+d.name+'.''+sh.name+''.''+o.name,c.name,c.column_id
from '+d.name+'.sys.columns c
inner join '+d.name+'.sys.objects o on c.object_id=o.object_id
INNER JOIN '+d.name+'.sys.schemas sh on o.schema_id=sh.schema_id
'
FROM sys.databases d
SELECT #SQL=RIGHT(#SQL,LEN(#SQL)-5)+'order by 1,3'
--print #SQL
EXEC (#SQL)
EDIT SQL Server 2000 version
DECLARE #SQL varchar(8000)
SET #SQL=''
SELECT #SQL=#SQL+'UNION
select
'''+d.name+'.''+sh.name+''.''+o.name,c.name,c.colid
from '+d.name+'..syscolumns c
inner join sysobjects o on c.id=o.id
INNER JOIN sysusers sh on o.uid=sh.uid
'
FROM master.dbo.sysdatabases d
SELECT #SQL=RIGHT(#SQL,LEN(#SQL)-5)+'order by 1,3'
--print #SQL
EXEC (#SQL)
EDIT
Based on some comments, here is a version using sp_MSforeachdb:
sp_MSforeachdb 'select
''?'' AS DatabaseName, o.name AS TableName,c.name AS ColumnName
from sys.columns c
inner join ?.sys.objects o on c.object_id=o.object_id
--WHERE ''?'' NOT IN (''master'',''msdb'',''tempdb'',''model'')
order by o.name,c.column_id'
Why not use
Select * From INFORMATION_SCHEMA.COLUMNS
You can make it DB specific with
Select * From DBNAME.INFORMATION_SCHEMA.COLUMNS
SELECT *
FROM information_schema.columns
WHERE column_name = 'My_Column'
You must set your current database name with USE [db_name] before this query.
Better way for you
sp_MSForEachDB #command1='USE ?;
SELECT
Table_Catalog
,Table_Schema
,Table_Name
,Column_Name
,Data_Type
,Character_Maximum_Length
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME like ''%ColumnNameHere%'''
Some minor improvements
->previous answers weren't showing all results
->possible to filter on column name by setting the column name variable
DECLARE #columnname nvarchar(150)
SET #columnname=''
DECLARE #SQL varchar(max)
SET #SQL=''
SELECT #SQL=#SQL+'UNION
SELECT
'''+d.name+'.''+sh.name+''.''+o.name COLLATE SQL_Latin1_General_CP1_CI_AS as name,c.name COLLATE SQL_Latin1_General_CP1_CI_AS as columnname,c.column_id
FROM '+d.name+'.sys.columns c
INNER JOIN '+d.name+'.sys.objects o on c.object_id=o.object_id
INNER JOIN '+d.name+'.sys.schemas sh on o.schema_id=sh.schema_id
WHERE c.name like ''%'+#columnname+'%'' AND sh.name<>''sys''
'
FROM sys.databases d
SELECT #SQL=RIGHT(#SQL,LEN(#SQL)-5)+'order by 1,3'
--print #SQL
EXEC (#SQL)
Normally I try to do whatever I can to avoid the use of cursors, but the following query will get you everything you need:
--Declare/Set required variables
DECLARE #vchDynamicDatabaseName AS VARCHAR(MAX),
#vchDynamicQuery As VARCHAR(MAX),
#DatabasesCursor CURSOR
SET #DatabasesCursor = Cursor FOR
--Select * useful databases on the server
SELECT name
FROM sys.databases
WHERE database_id > 4
ORDER by name
--Open the Cursor based on the previous select
OPEN #DatabasesCursor
FETCH NEXT FROM #DatabasesCursor INTO #vchDynamicDatabaseName
WHILE ##FETCH_STATUS = 0
BEGIN
--Insert the select statement into #DynamicQuery
--This query will select the Database name, all tables/views and their columns (in a comma delimited field)
SET #vchDynamicQuery =
('SELECT ''' + #vchDynamicDatabaseName + ''' AS ''Database_Name'',
B.table_name AS ''Table Name'',
STUFF((SELECT '', '' + A.column_name
FROM ' + #vchDynamicDatabaseName + '.INFORMATION_SCHEMA.COLUMNS A
WHERE A.Table_name = B.Table_Name
FOR XML PATH(''''),TYPE).value(''(./text())[1]'',''NVARCHAR(MAX)'')
, 1, 2, '''') AS ''Columns''
FROM ' + #vchDynamicDatabaseName + '.INFORMATION_SCHEMA.COLUMNS B
WHERE B.TABLE_NAME LIKE ''%%''
AND B.COLUMN_NAME LIKE ''%%''
GROUP BY B.Table_Name
Order BY 1 ASC')
--Print #vchDynamicQuery
EXEC(#vchDynamicQuery)
FETCH NEXT FROM #DatabasesCursor INTO #vchDynamicDatabaseName
END
CLOSE #DatabasesCursor
DEALLOCATE #DatabasesCursor
GO
I added a where clause in the main query (ex: B.TABLE_NAME LIKE ''%%'' AND B.COLUMN_NAME LIKE ''%%'') so that you can search for specific tables and/or columns if you want to.
To all: Thanks for all the post and comments some are good, but some are better.
The first big script is good because it is delivers just what is needed. The fastest and most detailed is the one suggestion for selecting from INFORMATION_SCHEMA.COLUMNS..
My need was to find all the errant columns of approximately the same name and Several databases.. Sooo, I made my versions of both (see below) ...Either of these two below script work and deliver the goods in seconds.
The assumption in other posts on this link, is that the first code example can be used successfully with for-each-database, is to me, not desirable. This is because the information is within the specific database and the simple use of the "fedb" doesn't produce the correct results, it simply doesn't give access. SOOO to that is why I use a CURSOR to collect the databases and ignore those that are Off-line, which in this case, a utility script, it is a good use of same.
Bottom Line, I read everyone's post, incorporated all the correction from the posts and made what are two very eloquent scripts from others good works. I listed both below and have also placed the script file on my public folder at OneDrive.com which you can access with this link: http://1drv.ms/1vr8yNX
Enjoy !
Hank Freeman
Senior Level - SQL Server DBA - Data Architect
Try them separately...
---------------------------
--- 1st example (works) ---
---------------------------
Declare
#DBName sysname
,#SQL_String1 nvarchar(4000)
,#SQL_String2 nvarchar(4000)
,#ColumnName nvarchar(200)
--set #ColumnName = 'Course_ID'
-------- Like Trick --------
-- IF you want to add more the #ColumnName so it looks like Course_ID,CourseID
-- then add an additional pairing of +''','''+'NewColumnSearchIDValue'
----------------------------
set #ColumnName = 'Course_ID' +''','''+'CourseID'
--select #ColumnName
-----
Declare #Column_Info table
(
[DatabaseName] nvarchar(128) NULL,
[ColumnName] sysname NULL,
[ObjectName] nvarchar(257) NOT NULL,
[ObjectType] nvarchar(60) NULL,
[DataType] nvarchar(151) NULL,
[Nullable] varchar(8) NOT NULL,
[MiscInfo] nvarchar(MAX) NOT NULL
)
--------------
Begin
set #SQL_String2 = 'SELECT
DB_NAME() as ''DatabaseName'',
s.name as ColumnName
,sh.name+''.''+o.name AS ObjectName
,o.type_desc AS ObjectType
,CASE
WHEN t.name IN (''char'',''varchar'') THEN t.name+''(''+CASE WHEN s.max_length<0 then ''MAX'' ELSE CONVERT(varchar(10),s.max_length) END+'')''
WHEN t.name IN (''nvarchar'',''nchar'') THEN t.name+''(''+CASE WHEN s.max_length<0 then ''MAX'' ELSE CONVERT(varchar(10),s.max_length/2) END+'')''
WHEN t.name IN (''numeric'') THEN t.name+''(''+CONVERT(varchar(10),s.precision)+'',''+CONVERT(varchar(10),s.scale)+'')''
ELSE t.name
END AS DataType
,CASE
WHEN s.is_nullable=1 THEN ''NULL''
ELSE ''NOT NULL''
END AS Nullable
,CASE
WHEN ic.column_id IS NULL THEN ''''
ELSE '' identity(''+ISNULL(CONVERT(varchar(10),ic.seed_value),'''')+'',''+ISNULL(CONVERT(varchar(10),ic.increment_value),'''')+'')=''+ISNULL(CONVERT(varchar(10),ic.last_value),''null'')
END
+CASE
WHEN sc.column_id IS NULL THEN ''''
ELSE '' computed(''+ISNULL(sc.definition,'''')+'')''
END
+CASE
WHEN cc.object_id IS NULL THEN ''''
ELSE '' check(''+ISNULL(cc.definition,'''')+'')''
END
AS MiscInfo
into ##Temp_Column_Info
FROM sys.columns s
INNER JOIN sys.types t ON s.system_type_id=t.user_type_id and t.is_user_defined=0
INNER JOIN sys.objects o ON s.object_id=o.object_id
INNER JOIN sys.schemas sh on o.schema_id=sh.schema_id
LEFT OUTER JOIN sys.identity_columns ic ON s.object_id=ic.object_id AND s.column_id=ic.column_id
LEFT OUTER JOIN sys.computed_columns sc ON s.object_id=sc.object_id AND s.column_id=sc.column_id
LEFT OUTER JOIN sys.check_constraints cc ON s.object_id=cc.parent_object_id AND s.column_id=cc.parent_column_id
--------------------------------------------
--- DBA - Hank 12-Feb-2015 added this specific where statement
-- where Upper(s.name) like ''COURSE%''
-- where Upper(s.name) in (''' + #ColumnName + ''')
-- where Upper(s.name) in (''cycle_Code'')
-- ORDER BY sh.name+''.''+o.name,s.column_id
order by 1,2'
--------------------
Declare DB_cursor CURSOR
FOR
SELECT name FROM sys.databases
--select * from sys.databases
WHERE STATE = 0
-- and Name not IN ('master','msdb','tempdb','model','DocxPress')
and Name not IN ('msdb','tempdb','model','DocxPress')
Open DB_cursor
Fetch next from DB_cursor into #DBName
While ##FETCH_STATUS = 0
begin
--select #DBName as '#DBName';
Set #SQL_String1 = 'USE [' + #DBName + ']'
set #SQL_String1 = #SQL_String1 + #SQL_String2
EXEC sp_executesql #SQL_String1;
--
insert into #Column_Info
select * from ##Temp_Column_Info;
drop table ##Temp_Column_Info;
Fetch next From DB_cursor into #DBName
end
CLOSE DB_cursor;
Deallocate DB_cursor;
---
select * from #Column_Info order by 2,3
----------------------------
end
---------------------------
Below is the Second script..
---------------------------
--- 2nd example (works) ---
---------------------------
-- This is by far the best/fastes of the lot for what it delivers.
--Select * into dbo.hanktst From Master.INFORMATION_SCHEMA.COLUMNS
--FileID: SCRIPT_Get_Column_info_(INFORMATION_SCHEMA.COLUMNS).sql
----------------------------------------
--FileID: SCRIPT_Get_Column_info_(INFORMATION_SCHEMA.COLUMNS).sql
-- Utility to find all columns in all databases or find specific with a like statement
-- Look at this line to find a: --> set #SQL_String2 = ' select * into ##Temp_Column_Info....
----------------------------------------
---
SET NOCOUNT ON
begin
Declare #hanktst TABLE (
[TABLE_CATALOG] NVARCHAR(128) NULL
,[TABLE_SCHEMA] NVARCHAR(128) NULL
,[TABLE_NAME] sysname NOT NULL
,[COLUMN_NAME] sysname NULL
,[ORDINAL_POSITION] INT NULL
,[COLUMN_DEFAULT] NVARCHAR(4000) NULL
,[IS_NULLABLE] VARCHAR(3) NULL
,[DATA_TYPE] NVARCHAR(128) NULL
,[CHARACTER_MAXIMUM_LENGTH] INT NULL
,[CHARACTER_OCTET_LENGTH] INT NULL
,[NUMERIC_PRECISION] TINYINT NULL
,[NUMERIC_PRECISION_RADIX] SMALLINT NULL
,[NUMERIC_SCALE] INT NULL
,[DATETIME_PRECISION] SMALLINT NULL
,[CHARACTER_SET_CATALOG] sysname NULL
,[CHARACTER_SET_SCHEMA] sysname NULL
,[CHARACTER_SET_NAME] sysname NULL
,[COLLATION_CATALOG] sysname NULL
,[COLLATION_SCHEMA] sysname NULL
,[COLLATION_NAME] sysname NULL
,[DOMAIN_CATALOG] sysname NULL
,[DOMAIN_SCHEMA] sysname NULL
,[DOMAIN_NAME] sysname NULL
)
Declare
#DBName sysname
,#SQL_String2 nvarchar(4000)
,#TempRowCnt varchar(20)
,#Dbug bit = 0
Declare DB_cursor CURSOR
FOR
SELECT name FROM sys.databases
WHERE STATE = 0
-- and Name not IN ('master','msdb','tempdb','model','DocxPress')
and Name not IN ('msdb','tempdb','model','DocxPress')
Open DB_cursor
Fetch next from DB_cursor into #DBName
While ##FETCH_STATUS = 0
begin
set #SQL_String2 = ' select * into ##Temp_Column_Info from [' + #DBName + '].INFORMATION_SCHEMA.COLUMNS
where UPPER(Column_Name) like ''COURSE%''
;'
if #Dbug = 1 Select #SQL_String2 as '#SQL_String2';
EXEC sp_executesql #SQL_String2;
insert into #hanktst
select * from ##Temp_Column_Info;
drop table ##Temp_Column_Info;
Fetch next From DB_cursor into #DBName
end
select * from #hanktst order by 4,2,3
CLOSE DB_cursor;
Deallocate DB_cursor;
set #TempRowCnt = (select cast(count(1) as varchar(10)) from #hanktst )
Print ('Rows found: '+ #TempRowCnt +' end ...')
end
--------
I just realized that the following query would give you all column names from the table in your database (SQL SERVER 2017)
SELECT DISTINCT NAME FROM SYSCOLUMNS
ORDER BY Name
OR SIMPLY
SELECT Name FROM SYSCOLUMNS
If you do not care about duplicated names.
Another option is SELECT Column names from INFORMATION_SCHEMA
SELECT DISTINCT column_name FROM INFORMATION_SCHEMA.COLUMNS
ORDER BY column_name
It is usually more interesting to have the TableName as well as the ColumnName ant the query below does just that.
SELECT
Object_Name(Id) As TableName,
Name As ColumnName
FROM SysColumns
And the results would look like
TableName ColumnName
0 Table1 column11
1 Table1 Column12
2 Table2 Column21
3 Table2 Column22
4 Table3 Column23
I used:
EXEC sp_MSforeachdb 'Use ? Select * From INFORMATION_SCHEMA.COLUMNS '
It seems to work for what I needed.
try the below query
DECLARE #Query VARCHAR(max)
SELECT #Query = 'USE ? SELECT ''?'' AS DataBaseName,
sys.columns.name AS ColumnName ,
sys.tables.name AS TableName ,
schema_name (sys.tables.schema_Id) AS schemaName
FROM sys.columns
JOIN sys.tables
ON sys.columns.object_id = sys.tables.object_id
WHERE sys.columns.name = ''id'' '
EXEC SP_MSFOREACHDB #Query
gives list of tables containing ID column from all databases.
SELECT sys.columns.name AS ColumnName, tables.name AS TableName
FROM sys.columns
JOIN sys.tables ON sys.columns.object_id = tables.object_id
user #KM say best Answer.
I Use This :
Declare #Table_Name VarChar(100) ,#Column_Name VarChar(100)
Set #Table_Name = ''
Set #Column_Name = ''
Select
RowNumber = Row_Number() Over( PARTITION BY T.[Name] Order By T.[Name],C.column_id ),
SCHEMA_NAME( T.schema_id ) As SchemaName ,
T.[Name] As Table_Name ,
C.[Name] As Field_Name ,
sysType.name ,
C.max_length , C.is_nullable , C.is_identity , C.scale , C.precision
From Sys.Tables As T
Left Join Sys.Columns As C On ( T.[Object_Id] = C.[Object_Id] )
Left Join sys.types As sysType On ( C.user_type_id = sysType.user_type_id )
Where ( Type = 'U' )
And ( C.Name Like '%' + #Column_Name + '%' )
And ( T.Name Like '%' + #Table_Name + '%' )
Minor refinement on KM's solution for those like me who've got collation fun on their DB server....
DECLARE #SQL varchar(max)=''
SELECT #SQL=#SQL+'UNION
select
'''+d.name +'.''+sh.name+''.''+o.name COLLATE SQL_Latin1_General_CP1_CI_AS,c.name COLLATE SQL_Latin1_General_CP1_CI_AS,c.column_id
from '+d.name +'.sys.columns c
inner join sys.objects o on c.object_id=o.object_id
INNER JOIN sys.schemas sh on o.schema_id=sh.schema_id
'
FROM sys.databases d
SELECT #SQL=RIGHT(#SQL,LEN(#SQL)-5)+'order by 1,3'
--print #SQL
EXEC (#SQL)
(Still living in hope that we'll find a way to do this that can be wrapped into a view.)
My solution for similar task was:
if object_id('tempdb..##temp_meta') is not null
drop table ##temp_meta
create table ##temp_meta(database_name sysname
, schema_name sysname
, table_name sysname
, column_name sysname
, column_id tinyint
, type_name sysname
, max_length int
, precision tinyint
, scale tinyint
, is_nullable bit
, is_identity bit)
exec sp_MSforeachdb '
if(''?'' not in (''master'', ''msdb'', ''model'', ''tempdb''))
begin
USE [?]
insert into ##temp_meta
SELECT
''?'',
s.[name] AS schema_name,
t.name AS table_name,
c.[name] as column_name,
c.column_id,
ty.name as type_name,
c.max_length,
c.precision,
c.scale,
c.is_nullable,
c.is_identity
FROM sys.columns c
JOIN sys.types ty
ON ty.system_type_id = c.system_type_id
JOIN sys.tables t
ON c.object_id = t.object_id
JOIN sys.schemas s
ON s.schema_id = t.schema_id
end'
sp_MSForEachDB #command1='USE ?;
SELECT
Table_Catalog
,Table_Schema
,Table_Name
,Column_Name
,Data_Type
,Character_Maximum_Length
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
--Data_Type = ''int''
--AND
COLUMN_NAME like ''%ColumnName%''
And
Table_name like ''%TableName%''
order by 1,2,3
'
Here, this is my code to search for a column name in all databases in the current instance:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: themah
-- Create date: 2022-10-09
-- Description: Looking for a column name in all databases in current instance, and list the db names
-- =============================================
CREATE OR ALTER PROCEDURE [dbo].[FindColumnNameInAllDatabases]
#columnNameToFind NVARCHAR (100)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #dbName VARCHAR(100)
DECLARE #queryEachDatabase NVARCHAR(MAX)
DECLARE dbNamesCursor CURSOR FOR
SELECT [Name]
FROM sys.databases AS d
WHERE d.name NOT IN ('master', 'tempdb', 'model', 'msdb')
OPEN dbNamesCursor
FETCH NEXT FROM dbNamesCursor INTO #dbName
WHILE (##FETCH_STATUS = 0)
BEGIN
SET #queryEachDatabase = N'IF Exists
(SELECT 1 FROM [' + #dbName + '].[INFORMATION_SCHEMA].[Columns] WHERE [Column_Name] Like N''%' + #columnNameToFind + '%'')
BEGIN
PRINT ''' + #dbName + '''
END
'
--PRINT #queryEachDatabase
EXEC(#queryEachDatabase)
FETCH NEXT FROM dbNamesCursor INTO #dbName
END
CLOSE dbNamesCursor
DEALLOCATE dbNamesCursor
END
GO
And a usage example : EXEC dbo.FindColumnNameInAllDb N'firstName'
Or another useful way to print the queries is this :
DECLARE #columnName NVARCHAR(100) = N'firstName'
SELECT
'SELECT * FROM [' + NAME + '].[INFORMATION_SCHEMA].[Columns] WHERE [Column_Name] Like N''%' + #columnName + '%'''
FROM [sys].[databases]

Drop all tables whose names begin with a certain string

How can I drop all tables whose names begin with a given string?
I think this can be done with some dynamic SQL and the INFORMATION_SCHEMA tables.
You may need to modify the query to include the owner if there's more than one in the database.
DECLARE #cmd varchar(4000)
DECLARE cmds CURSOR FOR
SELECT 'drop table [' + Table_Name + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE Table_Name LIKE 'prefix%'
OPEN cmds
WHILE 1 = 1
BEGIN
FETCH cmds INTO #cmd
IF ##fetch_status != 0 BREAK
EXEC(#cmd)
END
CLOSE cmds;
DEALLOCATE cmds
This is cleaner than using a two-step approach of generate script plus run. But one advantage of the script generation is that it gives you the chance to review the entirety of what's going to be run before it's actually run.
I know that if I were going to do this against a production database, I'd be as careful as possible.
Edit Code sample fixed.
SELECT 'DROP TABLE "' + TABLE_NAME + '"'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
This will generate a script.
Adding clause to check existence of table before deleting:
SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
This will get you the tables in foreign key order and avoid dropping some of the tables created by SQL Server. The t.Ordinal value will slice the tables into dependency layers.
WITH TablesCTE(SchemaName, TableName, TableID, Ordinal) AS
(
SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
OBJECT_NAME(so.object_id) AS TableName,
so.object_id AS TableID,
0 AS Ordinal
FROM sys.objects AS so
WHERE so.type = 'U'
AND so.is_ms_Shipped = 0
AND OBJECT_NAME(so.object_id)
LIKE 'MyPrefix%'
UNION ALL
SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
OBJECT_NAME(so.object_id) AS TableName,
so.object_id AS TableID,
tt.Ordinal + 1 AS Ordinal
FROM sys.objects AS so
INNER JOIN sys.foreign_keys AS f
ON f.parent_object_id = so.object_id
AND f.parent_object_id != f.referenced_object_id
INNER JOIN TablesCTE AS tt
ON f.referenced_object_id = tt.TableID
WHERE so.type = 'U'
AND so.is_ms_Shipped = 0
AND OBJECT_NAME(so.object_id)
LIKE 'MyPrefix%'
)
SELECT DISTINCT t.Ordinal, t.SchemaName, t.TableName, t.TableID
FROM TablesCTE AS t
INNER JOIN
(
SELECT
itt.SchemaName AS SchemaName,
itt.TableName AS TableName,
itt.TableID AS TableID,
Max(itt.Ordinal) AS Ordinal
FROM TablesCTE AS itt
GROUP BY itt.SchemaName, itt.TableName, itt.TableID
) AS tt
ON t.TableID = tt.TableID
AND t.Ordinal = tt.Ordinal
ORDER BY t.Ordinal DESC, t.TableName ASC
On Oracle XE this works:
SELECT 'DROP TABLE "' || TABLE_NAME || '";'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'
Or if you want to remove the constraints and free up space as well, use this:
SELECT 'DROP TABLE "' || TABLE_NAME || '" cascade constraints PURGE;'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'
Which will generate a bunch of DROP TABLE cascade constraints PURGE statements...
For VIEWS use this:
SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'
EXEC sp_MSforeachtable 'if PARSENAME("?",1) like ''%CertainString%'' DROP TABLE ?'
Edit:
sp_MSforeachtable is undocumented hence not suitable for production because it's behavior may vary depending on MS_SQL version.
Here is my solution:
SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%';
And of course you need to replace TABLE_PREFIX_GOES_HERE with your prefix.
I saw this post when I was looking for mysql statement to drop all WordPress tables based on #Xenph Yan here is what I did eventually:
SELECT CONCAT( 'DROP TABLE `', TABLE_NAME, '`;' ) AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'wp_%'
this will give you the set of drop queries for all tables begins with wp_
CREATE PROCEDURE usp_GenerateDROP
#Pattern AS varchar(255)
,#PrintQuery AS bit
,#ExecQuery AS bit
AS
BEGIN
DECLARE #sql AS varchar(max)
SELECT #sql = COALESCE(#sql, '') + 'DROP TABLE [' + TABLE_NAME + ']' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE #Pattern
IF #PrintQuery = 1 PRINT #sql
IF #ExecQuery = 1 EXEC (#sql)
END
Xenph Yan's answer was far cleaner than mine but here is mine all the same.
DECLARE #startStr AS Varchar (20)
SET #startStr = 'tableName'
DECLARE #startStrLen AS int
SELECT #startStrLen = LEN(#startStr)
SELECT 'DROP TABLE ' + name FROM sysobjects
WHERE type = 'U' AND LEFT(name, #startStrLen) = #startStr
Just change tableName to the characters that you want to search with.
This worked for me.
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += '
DROP TABLE '
+ QUOTENAME(s.name)
+ '.' + QUOTENAME(t.name) + ';'
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE t.name LIKE 'something%';
PRINT #sql;
-- EXEC sp_executesql #sql;
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'
-- Test is the table name
SELECT 'if object_id(''' + TABLE_NAME + ''') is not null begin drop table "' + TABLE_NAME + '" end;'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
I had to do a slight derivation on Xenph Yan's answer I suspect because I had tables not in the default schema.
SELECT 'DROP TABLE Databasename.schema.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'strmatch%'
In case of temporary tables, you might want to try
SELECT 'DROP TABLE "' + t.name + '"'
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'
I would like to post my proposal of the solution which DROP (not just generate and select a drop commands) all tables based on the wildcard (e.g. "table_20210114") older than particular amount of days.
DECLARE
#drop_command NVARCHAR(MAX) = '',
#system_time date,
#table_date nvarchar(8),
#older_than int = 7
Set #system_time = (select getdate() - #older_than)
Set #table_date = (SELECT CONVERT(char(8), #system_time, 112))
SELECT #drop_command += N'DROP TABLE ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME([Name]) + ';'
FROM <your_database_name>.sys.tables
WHERE [Name] LIKE 'table_%' AND RIGHT([Name],8) < #table_date
SELECT #drop_command
EXEC sp_executesql #drop_command
If your query returns more than one line, you can collect the results and merge them into a query.
declare #Tables as nvarchar(max) = '[schemaName].['
select #Tables =#Tables + TABLE_NAME +'],[schemaName].['
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_SCHEMA = 'schemaName'
AND TABLE_NAME like '%whateverYourQueryIs%'
select #Tables = Left(#Tables,LEN(#Tables)-13) --trying to remove last ",[schemaName].[" part, so you need to change this 13 with actual lenght
--print #Tables
declare #Query as nvarchar(max) = 'Drop table ' +#Tables
--print #Query
exec sp_executeSQL #Query
Try following code:
declare #TableLst table(TblNames nvarchar(500))
insert into #TableLst (TblNames)
SELECT 'DROP TABLE [' + Table_Name + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE Table_Name LIKE 'yourFilter%'
WHILE ((select COUNT(*) as CntTables from #TableLst) > 0)
BEGIN
declare #ForExecCms nvarchar(500) = (select top(1) TblNames from #TableLst)
EXEC(#ForExecCms)
delete from #TableLst where TblNames = #ForExecCms
END
This SQL script is executed without using a cursor.