SQl Server Query against Server Group - sql

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

Related

How to run the same parameter to 22 similar databases?

I have been pulling data from a single database that stores the data for 22 facilities together. The database has now been redesigned and there are 22 separate databases (similar) for each of the facilities that we have. How can use the same code and run it against all these databases at the same time? Like, how can I pass the same parameter and pull data from all 22 databases?
You can use CURSOR to achieve your requirement. Here I placed a sample Dynamic Insert Script which you can adjust as per your requirement. One manual task is you have to insert one by one 22 database name using script in a temporary table. The facility is that is is a one time work and you can re use the script when ever it is required.
--The first step will be creating a Table variable
--where you will INSERT all your database names
--for a further loop as below-
DECLARE #DbName VARCHAR(200)
DECLARE #DatabaseList TABLE (DbName VARCHAR(200))
INSERT INTO #DatabaseList (DbName) VALUES('db_name_1')
INSERT INTO #DatabaseList (DbName) VALUES('db_name_2')
--.......................
INSERT INTO #DatabaseList (DbName) VALUES('db_name_22')
--Now you can use CURSOR to generate the loop
--and execute your required script as shown below
DECLARE db_cursor CURSOR FOR
SELECT DbName FROM #DatabaseList
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #DbName
WHILE ##FETCH_STATUS = 0
BEGIN
--HERE You need to write your script That you
--Execute for all your database. I have added
--a sample script for your reference only
-- You can see the Database Name inserted in the Script Dynamically from the Loop.
--The script could be INSERT/Update/DELETE As per requirement
EXEC
(
'INSERT INTO '+#DbName+'.dbo.<Your_table_Name_Here>
SELECT * FROM master.dbo.<Your_table_Name_Here> '
)
--END OF Dynamic Part
FETCH NEXT FROM db_cursor INTO #DbName
END
CLOSE db_cursor
DEALLOCATE db_cursor

How to execute single sql query in multiple databases

I have cloud server where I've hosted a web application for my customers. Each customer has a different SQL database and website in IIS. Whenever I want to execute a sql query to update something, I have to do this manually in each database. There are almost 50 databases and it takes around an hour in executing single query each time. Can someone provide me a tool or way by which I just select all the database at once and execute that query simply?
If I guess you have all databases are in same structure and every time you run script to update something, the script basically same and you just run that same script one by one for each customer.
If the above case is true, you can use CURSOR to produce a Loop between your all databases and Execute necessary script to serve your purpose.
Note: This is not the solution, Just Idea.
--The first step will be creating a Table variable
--where you will INSERT all your database names
--for a further loop as below-
DECLARE #DbName VARCHAR(200)
DECLARE #DatabaseList TABLE (DbName VARCHAR(200))
INSERT INTO #DatabaseList (DbName) VALUES('db_name_1')
INSERT INTO #DatabaseList (DbName) VALUES('db_name_2')
--.......................
INSERT INTO #DatabaseList (DbName) VALUES('db_name_50')
--Now you can use CURSOR to generate the loop
--and execute your required script as shown below
DECLARE db_cursor CURSOR FOR
SELECT DbName FROM #DatabaseList
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #DbName
WHILE ##FETCH_STATUS = 0
BEGIN
--HERE You need to write your script That you
--Execute for all your database. I have added
--a sample script where I guess you updating
--certain tables in your all database WHERE ID = 1
-- You can see the Database Name inserted in the
-- Script Dynamically from the Loop
EXEC ('UPDATE '+#DbName+'.dbo.<Your_table_Name_Here>
WHERE ID=1')
--END OF Dynamic Part
FETCH NEXT FROM db_cursor INTO #DbName
END
CLOSE db_cursor
DEALLOCATE db_cursor

Table used in which stored procedure

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'''

Query that will apply to EVERY SQL Server database

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

Use “insert into” only with databases that has a certain table ( SQL Server 2008 R2 )

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