I'm testing a drop database query for all databases that begin with a specific prefix. However, because that can easily lead to horrific things I'm taking my drop database query
declare #dbname nvarchar (200);
declare #query nvarchar (max);
DECLARE db_cursor CURSOR FOR
select name from sys.databases
where name like 'PREFIX%'
Open db_cursor
fetch next from db_cursor into #dbname
while ##FETCH_STATUS = 0
BEGIN
set #query = 'Drop Database ['+ #dbname + ']'
Exec(#query)
FETCH NEXT FROM db_cursor INTO #dbname
END
Close db_cursor
deallocate db_cursor
and want to change the Drop Database part to something that is less scary.
So MAIN QUESTION is there a simple SQL query that I could put in there that would always apply to any SQL Server database? So I know that this query will only affect the databases I want it to before switching it back to Drop Database?
EDIT: Better yet, a query that will return the names of the databases.
Like select name from sys.databases but one that will work with ['+ #dbname + '] to return only the names of databases with that prefix to ensure that this query affects the appropriate databases.
Instead of Exec(#query), just call PRINT #query. That will show you the SQL that you intend to run.
PRINT Documentation
First of all just execute the following query and it will tell you what databases will it bring forward in the rest of the code
select name from sys.databases
where name like 'PREFIX%'
Finally add a PRINT statement to see the final DROP DATABASE statements dynamically build inside the cursor.
Some minor improvement in your code:
declare #dbname SYSNAME;
declare #query nvarchar (max);
DECLARE db_cursor CURSOR LOCAL FORWARD_ONLY FOR
select name from sys.databases
where name like 'PREFIX%'
Open db_cursor
fetch next from db_cursor into #dbname
while (##FETCH_STATUS = 0)
BEGIN
set #query = 'Drop Database '+ QUOTENAME(#dbname)
--Exec sp_executesql #query --<-- For execution
-- PRINT #query --<-- For debugging
FETCH NEXT FROM db_cursor INTO #dbname
END
Close db_cursor
deallocate db_cursor
Related
I am using SQL Server 2008 R2. I have multiple database restored one is master and other are version DB (TesDB, TestDB1,TestDB2 etc...)
I want to know one particular table is used in which stored procedure. I need list for databases.
Currently I am using below query but it's working only for one DB at a time.
use [TestDB]
GO
SELECT Name
FROM sys.Procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) = 'Testtable'
Please suggest.
do you mean something like?
declare #db varchar(50),
#sql nvarchar(max),
#tofind varchar(max)='table to find'
DECLARE db_cursor CURSOR FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #db
WHILE ##FETCH_STATUS = 0
BEGIN
set #sql='SELECT Name,OBJECT_DEFINITION(OBJECT_ID)FROM '+#db+'.sys.Procedures WHERE OBJECT_DEFINITION(OBJECT_ID) like ''%'+#tofind+'%'' '
print #sql
exec sp_executesql #sql
FETCH NEXT FROM db_cursor INTO #db
END
CLOSE db_cursor
DEALLOCATE db_cursor
Try using Redgate's Sql Search tool. It's fantastic for stuff like this.
http://www.red-gate.com/products/sql-development/sql-search/
exec sp_MSforeachdb 'use ? SELECT ? as DBName, Name FROM sys.Procedures WHERE OBJECT_DEFINITION(OBJECT_ID) = ''Testtable'''
I need to do a "log" with all the information of a certain table, of all databases, inside a new table that I will create (With the same structure).
But not all databases has this table.
I could make a query to find all databases that has this table I want:
SELECT name
FROM sys.databases
WHERE CASE
WHEN state_desc = 'ONLINE'
THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[tblLogdiscador]', 'U')
END IS NOT NULL
It will only list the databases with this table I want to log. But now I need to do a loop, to pass by all databases, inserting the information of the "tbllogdiscador" into the table I created. I was thinking in SP_MSFOREACHDB but I see a lot of people saying to not use it.
How can I loop trough all databases that has the table, and if it has, insert into the new log table??
The code below is not helping me:
exec sp_msforeachdb 'if ((select count(*)
from [?].sys.tables Where name in(''tbllogdiscador''))=1)
begin
insert into [The new tbl log]
select * from ?.dbo.tbllog
end
I'm trying to use a cursor, but i'm having problems.
Any Ideas how to do this with WHILE?
To do what you are thinking, you need some kind of process flow logic (A cursor seems to be the most fitting choice), and dynamic sql.
So the high level is we need to get all of the DB names, put them into the cursor, and then use the cursor to execute the dynamic sql statement where you test to see of the table exists, and pull the records if so.
Ok so here is an example cursor that loops through the DBs on a server looking for a particular table name, and if it exists, does something (you'll have to do the sql for #Sql2):
declare #DBName varchar(256)
declare #SQL1 nvarchar(max)
declare #Sql2 nvarchar(max)
DECLARE db_cursor CURSOR FOR
SELECT name
FROM sys.databases
WHERE state_desc = 'ONLINE'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #DBName
WHILE ##FETCH_STATUS = 0
Begin
set #SQL1 = 'Select Name from ' + #DBName + '.sys.objects where name = ''tblLogdiscador'' '
set #SQL2 = --Your select and insert statement selecting from #DBName + 'dbo.tbllogdiscador'
if exists(exec sp_executesql #Sql1)
begin
exec sp_executesql #sql2
end
FETCH NEXT FROM db_cursor INTO #DBName
end
close db_cursor
deallocate db_cursor
So I am using the tsql code to run through a bunch of servers, and look in each database for the users. My issue that on a specific server, there are databases I do not have access to and do not need to use. When the query runs on them it stops on the entire server and moves to the next one. I have been trying to find a way to exclude certain databses from the search.
What I am trying to do is
for example on server A excluded these databses B,C,D, and so on . I have tried where <> and != and does not work or I have the wrong syntax
USE MASTER
If OBJECT_ID('#TDB', 'U') > 0
Drop Table #TDB
DECLARE #dbname varchar(200),
#sql varchar(max)
CREATE TABLE #TDB (
DataBaseName nvarchar(200),
UserName nvarchar(200)
)
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases WHERE DBID>4
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #dbname
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql='insert into #TDb(DataBaseName,UserName)
select '''+#dbname+''' DataBaseName,[user_name] UserName FROM '+#dbname+'.[dbo].[USERS] where'+#dbname+'<>[APSSWATCH]'
EXEC(#sql)
FETCH NEXT FROM db_cursor INTO #dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor
SELECT * FROM #TDB ORDER BY DataBaseName,UserName
DROP TABLE #TDB
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases WHERE DBID>4 and name<> 'APSSWATCH'
You can remove this one:
where'+#dbname+'<>[APSSWATCH]'
Thank you for leading me into the right direction though, instad of
name<>'APPSWATCH'
I used
name NOT IN 'APPSWATCH'
and it works
I have 3000+ tables in my SQL 2008 database with names like listed below, that all starts with tempBinary_, that I need to delete programmatically, how do I do that?
I don't know if I prefer the solution in a SQL-script or with use of LINQtoSQL, i guess both are fine.
tempBinary_002c90322f4e492795a0b8a14e2f7c99
tempBinary_0039f7db05a9456f96eb3cd6a788225a
tempBinary_0057da9ef0d84017b3d0bbcbfb934fb2
I've used Like before on columns, but I don't know if it good for table names too.
Maybe something like this, where LIKE is used, can do it? I don't know.
Use [dbo].[database_name]
DROP TABLE table_name
WHERE table_name LIKE 'tempBinary_%'
Any ideas?
declare #stmt varchar(max) = ''
declare #tbl_name varchar(255)
DECLARE tbl_cursor CURSOR FORWARD_ONLY READ_ONLY
FOR select name
from sysobjects
where xtype='u' and name like 'tempBinary%'
OPEN tbl_cursor
FETCH NEXT FROM tbl_cursor
INTO #tbl_name;
WHILE ##FETCH_STATUS = 0
BEGIN
set #stmt = #stmt + 'drop table ' + #tbl_name + ';' + CHAR(13)
FETCH NEXT FROM tbl_cursor
INTO #tbl_name
end
CLOSE tbl_cursor;
DEALLOCATE tbl_cursor;
execute sp_sqlexec #stmt
Let's say I have some update script:
update sometable set somecolumn = 'somevalue' where xyz = 0
Now let's say I have multiple databases, like DB1, DB2, DB3 and so on. How could I run this script on all of them without doing it manually?
Thanks :)
You can do this using cursor
get list of all server in your lan or in network
create cursor for that
Than make use of sp_executesql to run you update script with forpart query
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [sp_cross_db_query]
#SQLQuery varchar(400)
AS
DECLARE #DB_Name varchar(100)
DECLARE database_cursor CURSOR FOR
SELECT DatabaseName
FROM Management.dbo.Customers
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO #DB_Name
WHILE ##FETCH_STATUS = 0
BEGIN
exec(
'USE [' + #DB_Name + '];' +
#SQLQuery
)
FETCH NEXT FROM database_cursor INTO #DB_Name
END
CLOSE database_cursor
DEALLOCATE database_cursor
to run the query
exec sp_cross_db_query 'SELECT count(*) FROM Products'
If you wanted all databases, you can use sp_MSforeachdb:
http://www.databasejournal.com/features/mssql/article.php/3441031/SQL-Server-Undocumented-Stored-Procedures-spMSforeachtable-and-spMSforeachdb.htm
EXEC sp_MSforeachdb #command1="UPDATE ?..sometable SET somecolumn='somevalue' WHERE xyz=0"
Or for specific databases, you could try some of the logic as seen here:
http://www.sqlservercurry.com/2009/04/6-common-uses-of-undocumented-stored.html
Hope that helps.