0

I am looking to run a query over multiple databases. I've seen this function;

sp_MsForEachDb

Which is ok, but it runs through all the databases and I only want to use some of them. Is there a way to select which databases are run? Also within those databases, we have branches (so all the tables have a BranchID column). For example, Database 1 might have branches 4, 5 and 6 and we only want branch 5. Database 2 might also have branches 4, 5 and 6, but in this one we want branches 4 and 5. Is there a way to select which branch is run according to which database is being run?

COuld this be done on SSIS or something similar?

Hope this makes sense!

4
  • I would imagine a select from sys.databases, plus "where in" statement for branches. Commented Dec 7, 2015 at 11:09
  • How do you use sys.databases? I've not done that before... Commented Dec 7, 2015 at 11:52
  • it's a view in sql server master db which contains database information. just try select * from sys.databases. Also msdn msdn.microsoft.com/en-us/library/ms178534.aspx Commented Dec 7, 2015 at 11:58
  • you can get the db_id, names etc from there, along with other info that might be useful. Commented Dec 7, 2015 at 12:01

1 Answer 1

1

I use a simple cursor to accomplish this....it's pretty straight forward and you can run any statement within it, against the list of databases.

    --Drop temporary tables if they already exists.
IF OBJECT_ID('tempdb..#DatabaseNames') IS NOT NULL
    DROP TABLE #DatabaseNames

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results

--Create a temporary table.
CREATE TABLE #DatabaseNames
(
    DBName varchar(100),
    Active bit
)

GO

--Create a temporary table to store results.
CREATE TABLE #Results
(
    FirstName varchar(100),
    WebLogin varchar(100)
)

GO

--It's the long way to do this but just showing for the sake of the example.
INSERT INTO #DatabaseNames
VALUES ('Database1', 1)

INSERT INTO #DatabaseNames
VALUES ('Database2', 0)

INSERT INTO #DatabaseNames
VALUES ('Database3', 1)

INSERT INTO #DatabaseNames
VALUES ('TIER1', 1)

INSERT INTO #DatabaseNames
VALUES ('Northwind', 1)

DECLARE @DBName varchar(20)
DECLARE @SQL   varchar(2000)

--Start cursor
DECLARE LoopCursor CURSOR FOR
    SELECT DBName AS 'DBName'
    FROM #DatabaseNames
    WHERE DBName NOT IN ('TIER1', 'Northwind')
    AND Active = 1

    OPEN LoopCursor

    FETCH NEXT FROM LoopCursor
    INTO @DBName

    WHILE @@FETCH_STATUS = 0
    BEGIN

        SET @SQL = '
        INSERT INTO #Results
        SELECT FirstName, WebLogin
        FROM ' + @DBName + '.dbo.Users
        WHERE FirstName = ''User1''
        AND LastName = ''User1''
        AND WebLogin = ''User1Login'''

        EXEC(@SQL)
        --Print @DBName

        FETCH NEXT FROM LoopCursor
        INTO @DBName
    END

    SELECT *
    FROM #Results

    CLOSE LoopCursor
    DEALLOCATE LoopCursor

I modified my answer again to go with your last comment about wanting all the results in one table. You can add another temporary table and just insert the data into that. Then once done, select from that table before closing the cursor. As for having many criteria in the WHERE clause, you can enclose single quotes with 2 singles quotes, so WHERE name = 'MyName' becomes WHERE name = ''MyName''

BTW, I cursors aren't the most CPU friendly and most don't like using them but they have their place. I'm not suggesting this is the best solution but it works well. We have over 75 customer databases, all having the same structure, and I use this daily to update user fields and other table fields. It runs pretty fast for executing so many statements on so many databases.

Sign up to request clarification or add additional context in comments.

4 Comments

That looks really useful. What could I replace the configuration table with as I don't have one?
Ah I see. Is there any way to get the results to all be in one table instead of one per database. Union All or something. Otherwise I'm going to have to copy and paste every single table into excel (and there's about 75).
Are the fields all the same from each database?
yes they are so that should be fine. Also I have a lot of date criteria in the where clauses, how do I get them in, given they need single quote marks? Thank you so much for your help with this!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.