Get row count for a list of tables - sql

In SQL Server 2008, how can I get a row count for a list of tables?
I have a database where I would like to get the row count for all tables that begin with 'BB'
I've tried multiple variations of this:
CREATE TABLE #RowCounts(NumberOfRows BIGINT, TableName VARCHAR(128))
EXEC sp_MSforeachtable 'INSERT INTO #RowCounts
SELECT COUNT_BIG(*) AS NumberOfRows,
''?'' AS TableName FROM ?'
SELECT TableName, NumberOfRows
FROM #RowCounts
ORDER BY NumberOfRows DESC, TableName
DROP TABLE #RowCounts
Throwing in stuff like ''?'' AS TableName FROM ? WHERE ? LIKE 'BB%'
and ''?'' AS TableName FROM ? WHERE ''?'' LIKE 'BB%'
I'm sure that there has to be a way to do this. If you can get the rowcount for all tables, you should be able to get it for some tables...right?

try using sys.dm_db_partition_stats DMV..
select
object_name(object_id) as tablename,sum(row_count) as totalrows
from sys.dm_db_partition_stats
where object_name(object_id) like 'Bb%'--gives tables count which start with bb*
group by object_id
This may not be accurate enough (very little deviation) when you have lot of inserts ,deletes and check the count immediately..
if you are bent on using sp_msforeach..
CREATE TABLE #counts
(
table_name varchar(255),
row_count int
)
EXEC sp_MSForEachTable #command1='INSERT #counts (table_name, row_count) SELECT ''?'', COUNT(*) FROM ?'
SELECT table_name, row_count FROM #counts where table_name like 'BB%' ORDER BY table_name, row_count DESC
References:
How to fetch the row count for all tables in a SQL SERVER database

If database contains heap or clusterd index tables then I would use one of following approaches:
1) sys.partitions.rows
SELECT s.name as schema_name, t.name as table_name, SUM(p.rows) AS SumOfRows
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.partitions p ON p.object_id = t.object_id
WHERE s.name = N'dbo' AND t.name LIKE N'BB%'
GROUP BY s.name, t.name
But rows column isn't accurate (according to MSDN).
2) Or, if I would like accurate numbers then I would use COUNT(*) thus
DECLARE #SqlStatement NVARCHAR(MAX) = N''
SELECT #SqlStatement =
#SqlStatement
+ N' UNION ALL SELECT '
+ '''' + full_name + ''''
+ N' AS full_name, COUNT(*) AS row_count FROM ' + full_name
FROM (
SELECT QUOTENAME(s.name) + N'.' + QUOTENAME(t.name) AS full_name
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
WHERE s.name = N'dbo' AND t.name LIKE N'BB%'
) s
SET #SqlStatement = STUFF(#SqlStatement, 1, 10, N'')
EXEC sp_executesql #SqlStatement

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

Retrieving which database(s) and tables contains a spesific column name within a multiple database soloution

I wish do retrieve the database which contains table x, based on a column name I enter through e.g. My WHERE statement.
As of now, I run two seperate SELECT queries. Firstly, I search for which tables in the soloution contains a spesific column.
Second, I have to manually search for all the resulting databases in the subquery.
I wish to have this dynamic, so that when entering the column name, both database and table are returned. Now, I get "NULL" the Database column.
I've managed to get the current db using only db_name, but that is not what I intend to do..
db_name(db_id(table1.name)) AS "Database" , table1.name AS 'Table', column1.name AS 'Column'
FROM sys.columns column1
JOIN sys.tables table1 ON column1.object_id = table1.object_id
WHERE column1.name LIKE 'columnname'
ORDER BY "Table", "Column"
(SELECT "db" FROM sys.databases WHERE CASE WHEN state_desc = 'ONLINE' THEN
OBJECT_ID(QUOTENAME("db") + '.[dbo].' + '[database1]', 'U')
END IS NOT NULL)
The code above is working wiithout errors. However, I do not manage to pull the Database name, and I can not understand how I could solve this.
I've used several earlier posts as reference to build up this code, as I'm a rookie to SQL.. :-)
Thanks in advance for any assitance.
Br.
This gives a bit more information than you requested, but it's a code that I had to create a data dictionary of my databases. You just need to change the value for the first variable to make it work.
--Change this value
DECLARE #ColumnName sysname = 'YourColumnName';
IF OBJECT_ID( 'tempdb..#DataDictionary') IS NOT NULL
DROP TABLE #DataDictionary;
CREATE TABLE #DataDictionary(
TABLE_CATALOG sysname,
TABLE_SCHEMA sysname,
TABLE_NAME sysname,
ORDINAL_POSITION int,
COLUMN_NAME sysname,
DATA_TYPE sysname,
IS_NULLABLE varchar(8)
);
DECLARE #SQL NVARCHAR(MAX);
DECLARE dbs CURSOR LOCAL FAST_FORWARD
FOR
SELECT REPLACE( 'USE <<database_name>>;
INSERT INTO #DataDictionary
SELECT DB_NAME() AS TABLE_CATALOG,
s.name AS TABLE_SCHEMA,
t.name AS TABLE_NAME,
COLUMNPROPERTY(c.object_id, c.name, ''ordinal'') AS ORDINAL_POSITION,
c.name AS COLUMN_NAME,
CASE WHEN ty.name IN (''char'', ''varchar'', ''varbinary'', ''binary'') THEN CONCAT( ty.name, ''('', ISNULL( CAST(NULLIF(c.max_length, -1) AS varchar(4)), ''MAX''), '')'')
WHEN ty.name IN (''nchar'', ''nvarchar'') THEN CONCAT( ty.name, ''('', ISNULL( CAST(NULLIF(c.max_length, -1)/2 AS varchar(4)), ''MAX''), '')'')
WHEN ty.name IN (''numeric'', ''decimal'') THEN CONCAT( ty.name, ''('', c.precision, '','', c.scale, '')'')
ELSE ty.name END AS DATA_TYPE,
IIF(c.is_nullable = 1, ''NULL'', ''NOT NULL'') AS IS_NULLABLE
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE t.object_id NOT IN( SELECT major_id FROM sys.extended_properties WHERE minor_id = 0 AND class = 1 AND name = N''microsoft_database_tools_support'')
AND c.name = #ColumnName;', '<<database_name>>', name)
FROM sys.databases
WHERE database_id > 4 --No system databases
AND HAS_DBACCESS( name) = 1
AND state_desc = 'ONLINE'
OPEN dbs;
FETCH NEXT FROM dbs INTO #SQL;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC sp_executesql #SQL, N'#ColumnName sysname', #ColumnName;
FETCH NEXT FROM dbs INTO #SQL;
END;
CLOSE dbs;
DEALLOCATE dbs;
SELECT *
FROM #DataDictionary
ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION;
To get all the columns, just remove the column name comparison in the dynamic code AND c.name = #ColumnName

Count of Columns in temp table in SQL Server

Is there a way to count number of columns in a temp (#temptable) table in sql server ?
SELECT COUNT(*)
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..#mytemptable')
Query to get column counts for specified table
SELECT Count(*) as cnt into #TempTable FROM INFORMATION_SCHEMA.Columns where TABLE_NAME = 'TableName'
Query to get column names for specified table
SELECT COLUMN_NAME into #TempTable FROM INFORMATION_SCHEMA.Columns where TABLE_NAME = 'TableName'
Query to get column count for #TempTable
SELECT COUNT(*) as Cnt FROM tempdb.sys.columns WHERE object_id = object_id('tempdb..#TempTable')
DROP table #TempTable
You can use this query :
Declare #TableName NVarChar(150)
Declare #ColumnName NVarChar(150)
Set #TableName = ''
Set #ColumnName = ''
SELECT
t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns As C ON t.OBJECT_ID = c.OBJECT_ID
Where
( T.name Like '%' + #TableName + '%' )
And
( C.name Like '%' + #ColumnName + '%' )
SELECT
COUNT(C.Name) Count_Of_Columns,
COUNT(Distinct T.Name) Count_Of_Tables
FROM sys.tables AS t
INNER JOIN sys.columns As C ON t.OBJECT_ID = c.OBJECT_ID
Where
( T.name Like '%' + #TableName + '%' )
And
( C.name Like '%' + #ColumnName + '%' )
SELECT COUNT(*) FROM temptable

How to fetch the row count for all tables in a SQL SERVER database [duplicate]

This question already has answers here:
Query to list number of records in each table in a database
(23 answers)
Closed 8 years ago.
I am searching for a SQL Script that can be used to determine if there is any data (i.e. row count) in any of the tables of a given database.
The idea is to re-incarnate the database in case there are any rows existing (in any of the database).
The database being spoken of is Microsoft SQL SERVER.
Could someone suggest a sample script?
The following SQL will get you the row count of all tables in a database:
CREATE TABLE #counts
(
table_name varchar(255),
row_count int
)
EXEC sp_MSForEachTable #command1='INSERT #counts (table_name, row_count) SELECT ''?'', COUNT(*) FROM ?'
SELECT table_name, row_count FROM #counts ORDER BY table_name, row_count DESC
DROP TABLE #counts
The output will be a list of tables and their row counts.
If you just want the total row count across the whole database, appending:
SELECT SUM(row_count) AS total_row_count FROM #counts
will get you a single value for the total number of rows in the whole database.
If you want to by pass the time and resources it takes to count(*) your 3million row tables. Try this per SQL SERVER Central by Kendal Van Dyke.
Row Counts Using sysindexes
If you're using SQL 2000 you'll need to use sysindexes like so:
-- Shows all user tables and row counts for the current database
-- Remove OBJECTPROPERTY function call to include system objects
SELECT o.NAME,
i.rowcnt
FROM sysindexes AS i
INNER JOIN sysobjects AS o ON i.id = o.id
WHERE i.indid < 2 AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY o.NAME
If you're using SQL 2005 or 2008 querying sysindexes will still work but Microsoft advises that sysindexes may be removed in a future version of SQL Server so as a good practice you should use the DMVs instead, like so:
-- Shows all user tables and row counts for the current database
-- Remove is_ms_shipped = 0 check to include system objects
-- i.index_id < 2 indicates clustered index (1) or hash table (0)
SELECT o.name,
ddps.row_count
FROM sys.indexes AS i
INNER JOIN sys.objects AS o ON i.OBJECT_ID = o.OBJECT_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 ORDER BY o.NAME
Works on Azure, doesn't require stored procs.
SELECT t.name AS table_name
,s.row_count AS row_count
FROM sys.tables t
JOIN sys.dm_db_partition_stats s
ON t.OBJECT_ID = s.OBJECT_ID
AND t.type_desc = 'USER_TABLE'
AND t.name NOT LIKE '%dss%' --Exclude tables created by SQL Data Sync for Azure.
AND s.index_id IN (0, 1)
ORDER BY table_name;
Credit.
This one looks better than the others I think.
USE [enter your db name here]
GO
SELECT SCHEMA_NAME(A.schema_id) + '.' +
--A.Name, SUM(B.rows) AS 'RowCount' Use AVG instead of SUM
A.Name, AVG(B.rows) AS 'RowCount'
FROM sys.objects A
INNER JOIN sys.partitions B ON A.object_id = B.object_id
WHERE A.type = 'U'
GROUP BY A.schema_id, A.Name
GO
Short and sweet
sp_MSForEachTable 'DECLARE #t AS VARCHAR(MAX);
SELECT #t = CAST(COUNT(1) as VARCHAR(MAX))
+ CHAR(9) + CHAR(9) + ''?'' FROM ? ; PRINT #t'
Output:
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)
GROUP BY sc.name,ta.name
ORDER BY SUM(pa.rows) DESC
SQL Server 2005 or later gives quite a nice report showing table sizes - including row counts etc. It's in Standard Reports - and it is Disc Usage by Table.
Programmatically, there's a nice solution at:
http://www.sqlservercentral.com/articles/T-SQL/67624/
Don't use SELECT COUNT(*) FROM TABLENAME, since that is a resource intensive operation. One should use SQL Server Dynamic Management Views or System Catalogs to get the row count information for all tables in a database.
I would make a minor change to Frederik's solution. I would use the sp_spaceused system stored procedure which will also include data and index sizes.
declare c_tables cursor fast_forward for
select table_name from information_schema.tables
open c_tables
declare #tablename varchar(255)
declare #stmt nvarchar(2000)
declare #rowcount int
fetch next from c_tables into #tablename
while ##fetch_status = 0
begin
select #stmt = 'sp_spaceused ' + #tablename
exec sp_executesql #stmt
fetch next from c_tables into #tablename
end
close c_tables
deallocate c_tables
Here's a dynamic SQL approach that also gives you the schema as well:
DECLARE #sql nvarchar(MAX)
SELECT
#sql = COALESCE(#sql + ' UNION ALL ', '') +
'SELECT
''' + s.name + ''' AS ''Schema'',
''' + t.name + ''' AS ''Table'',
COUNT(*) AS Count
FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
FROM sys.schemas s
INNER JOIN sys.tables t ON t.schema_id = s.schema_id
ORDER BY
s.name,
t.name
EXEC(#sql)
If needed, it would be trivial to extend this to run over all databases in the instance (join to sys.databases).
select all rows from the information_schema.tables view, and issue a count(*) statement for each entry that has been returned from that view.
declare c_tables cursor fast_forward for
select table_name from information_schema.tables
open c_tables
declare #tablename varchar(255)
declare #stmt nvarchar(2000)
declare #rowcount int
fetch next from c_tables into #tablename
while ##fetch_status = 0
begin
select #stmt = 'select #rowcount = count(*) from ' + #tablename
exec sp_executesql #stmt, N'#rowcount int output', #rowcount=#rowcount OUTPUT
print N'table: ' + #tablename + ' has ' + convert(nvarchar(1000),#rowcount) + ' rows'
fetch next from c_tables into #tablename
end
close c_tables
deallocate c_tables
This is my favorite solution for SQL 2008 , which puts the results into a "TEST" temp table that I can use to sort and get the results that I need :
SET NOCOUNT ON
DBCC UPDATEUSAGE(0)
DROP TABLE #t;
CREATE TABLE #t
(
[name] NVARCHAR(128),
[rows] CHAR(11),
reserved VARCHAR(18),
data VARCHAR(18),
index_size VARCHAR(18),
unused VARCHAR(18)
) ;
INSERT #t EXEC sp_msForEachTable 'EXEC sp_spaceused ''?'''
SELECT * INTO TEST FROM #t;
DROP TABLE #t;
SELECT name, [rows], reserved, data, index_size, unused FROM TEST \
WHERE ([rows] > 0) AND (name LIKE 'XXX%')
SELECT
SUM(sdmvPTNS.row_count) AS [DBRows]
FROM
sys.objects AS sOBJ
INNER JOIN sys.dm_db_partition_stats AS sdmvPTNS
ON sOBJ.object_id = sdmvPTNS.object_id
WHERE
sOBJ.type = 'U'
AND sOBJ.is_ms_shipped = 0
AND sdmvPTNS.index_id < 2
GO

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.