How to run the same parameter to 22 similar databases? - sql

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

Related

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

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

Fetch SQL Server stored procedure output results into table

I have tried some solutions from the internet but they are not working for me .
My task is to get the out put of stored procedure into a table.The data is being inserted inside a cursor by loop . I am creating temporary table to store and display the data.
My code:
ALTER procedure [dbo].[usp_Test]
AS
SET NOCOUNT ON;
declare #caseId int;
declare #CHG_ID int;
declare #HEAR_ID int;
SET #CHG_ID = 1
set #testid = 1;
DECLARE db_cursor CURSOR FOR
SELECT C_CASE_ID
FROM table1 // tHERE WILL BE MULTIPLE CASEIDS
-- here I am trying to delete the temporary table, but it does not work
IF OBJECT_ID('tempdb..##test_temp_table') IS NOT NULL
TRUNCATE TABLE ##test_temp_table
ELSE
CREATE TABLE test_temp_table(HEAR_ID int)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #caseId
WHILE ##FETCH_STATUS = 0
BEGIN
insert into test_temp_table
EXEC STOREDPROCTEST2 #caseId, 1, #HEAR_ID OUTPUT;
-- LOOP THROUGH THE CURSOR TO GET ALL CASE IDS
FETCH NEXT FROM db_cursor INTO #caseId
SELECT HEAR_ID FROM test_temp_table;
END
CLOSE db_cursor
DEALLOCATE db_cursor;
I have two issues:
I cannot delete the temporary table
I am not seeing any output from the temporary table
[##test_temp_table] and [test_temp_table] are two different tables. First one is a global temp table, second one is a user table. I believe you want to replace the user table with the global temp table, i.e. replace object [test_temp_table] with [##test_temp_table]. or vice versa. In the end, you have to ensure you are querying the correct table.

Iterate through sql script using different values

Here is part of my script:
DECLARE #dataId int = 123
-- Here I run more SQL scripts using #dataId
Select from table A where id = #dataId
-- So on it goes in other tables and delete and update other tables
My question is there a way I can enter 100 values in #dataId and it will iterate through the script in an order? Is there a simpler way to do this in SQL Server 2008 rather then manually entering #dataId each time?
Well, according to your comment, then I guess that CURSORS are the way to go. Something like this should do:
DECLARE #dataId int
DECLARE DataIds CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR
SELECT DataId
FROM YourTableWithDataIdsHere
OPEN DataIds
FETCH NEXT FROM DataIds INTO #dataId
WHILE ##FETCH_STATUS = 0
BEGIN
-- Here I run more SQL scripts using #dataId
Select from table A where id = #dataId
-- So on it goes in other tables and delete and update other tables
FETCH NEXT FROM DataIds INTO #dataId
END
CLOSE DataIds
DEALLOCATE DataIds

SQl Server Query against Server Group

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