Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 SQL Server Administration (2008)
 Maintaning DBs

Author  Topic 

chris_cs
Posting Yak Master

223 Posts

Posted - 2011-07-18 : 09:47:45
We have a couple of servers with a large amount of databases on them so we want to run things such as DBCC statements on batches of databases at a time.

I created the following script but my cursor doesn't seem to be working at all:

USE DBAdmin
GO

IF OBJECT_ID ( 'usp_MaintainDBs', 'P' ) IS NOT NULL
DROP PROCEDURE usp_MaintainDBs;
GO

CREATE PROCEDURE usp_MaintainDBs @batchNo SMALLINT
AS
DECLARE @dbId INT
DECLARE @dbName VARCHAR(100)
DECLARE @sql VARCHAR(1000)

-- Check table to hold database list exists
IF OBJECT_ID('dbo.DbsToMaintain', 'U') IS NULL
BEGIN

CREATE TABLE DbsToMaintain
(
DatabaseID INT NOT NULL,
DatabaseName VARCHAR(100) NOT NULL,
LastDateMaintained SMALLDATETIME NULL
)
END
-- Check if every database has been processed. If so, reset the date fields to NULL
IF (SELECT COUNT(*) FROM DbsToMaintain WHERE LastDateMaintained IS NULL) = 0
BEGIN
UPDATE DbsToMaintain SET LastDateMaintained = NULL
END

-- Get all of the databases to be included in the maintenance routine and check for newly created ones
INSERT INTO DbsToMaintain
SELECT sd.database_id, sd.name, NULL
FROM sys.databases sd
LEFT OUTER JOIN DbsToMaintain dtm ON dtm.databaseid = sd.database_id
WHERE sd.database_id NOT IN (1, 2, 3, 4)
AND dtm.DatabaseID IS NULL
ORDER BY database_id

-- Remove any databases form the table that no longer reside on the server
DELETE FROM DbsToMaintain
WHERE DatabaseID NOT IN (SELECT database_id FROM sys.databases)

-- Create a cursor to loop through the databases
SET @sql = 'DECLARE db_Cursor CURSOR FOR'
+ ' SELECT TOP ' + CONVERT(VARCHAR, @batchNo) + ' DatabaseID, DatabaseName FROM DbsToMaintain WHERE LastDateMaintained IS NULL'
+ ' OPEN db_Cursor'
+ ' FETCH NEXT FROM db_Cursor INTO ' + CONVERT(VARCHAR, @dbId) + ', ' + @dbName
+ ' WHILE @@FETCH_STATUS = 0'
+ ' BEGIN'
+ ' UPDATE DbsToMaintain SET LastDateMaintained = GETDATE() WHERE DatabaseID = ' + CONVERT(VARCHAR, @dbId)
+ ' PRINT ' + @dbName + ' processed'
+ ' FETCH NEXT FROM db_Cursor INTO ' + CONVERT(VARCHAR, @dbId) + ', ' + @dbName
+ ' END'
+ ' CLOSE db_Cursor'
+ ' DEALLOCATE db_Cursor'
EXEC(@sql)
go


Is there anything obvious as to why this isn't working?

Junior DBA learning the ropes

russell
Pyro-ma-ni-yak

5072 Posts

Posted - 2011-07-18 : 10:11:17
Why are you using a cursor?
Why are you dynamically setting the cursor SQL?

Anyway, if you change your EXEC to PRINT, and copy/paste the result, you'll find the syntax errors.
declare @batchNo int
DECLARE @dbId INT
DECLARE @dbName VARCHAR(100)
set @batchNo = 2
set @dbId = 5
set @dbName = 'test'

declare @sql varchar(max)
SET @sql = 'DECLARE db_Cursor CURSOR FOR'
+ ' SELECT TOP ' + CONVERT(VARCHAR, @batchNo) + ' DatabaseID, DatabaseName FROM DbsToMaintain WHERE LastDateMaintained IS NULL'
+ ' OPEN db_Cursor'
+ ' FETCH NEXT FROM db_Cursor INTO ' + CONVERT(VARCHAR, @dbId) + ', ' + @dbName
+ ' WHILE @@FETCH_STATUS = 0'
+ ' BEGIN'
+ ' UPDATE DbsToMaintain SET LastDateMaintained = GETDATE() WHERE DatabaseID = ' + CONVERT(VARCHAR, @dbId)
+ ' PRINT ' + @dbName + ' processed'
+ ' FETCH NEXT FROM db_Cursor INTO ' + CONVERT(VARCHAR, @dbId) + ', ' + @dbName
+ ' END'
+ ' CLOSE db_Cursor'
+ ' DEALLOCATE db_Cursor'
print(@sql)


Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '5'.
Msg 128, Level 15, State 1, Line 1
The name "test" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '5'.
Go to Top of Page

chris_cs
Posting Yak Master

223 Posts

Posted - 2011-07-18 : 10:45:25
I'm aware I can use a while loop instead of a cursor but I just wanted to get the method working for now using a cursor.

I used dynamic SQL because I wanted to use a parameter in the SELECT TOP statement. If there is a better way of doing this I'm open to suggestions??

Thanks for the tip on using print. I'll have a look.

Junior DBA learning the ropes
Go to Top of Page

russell
Pyro-ma-ni-yak

5072 Posts

Posted - 2011-07-18 : 11:17:01
[code]DECLARE db_Cursor CURSOR
FOR
SELECT TOP (@batchNo) DatabaseID, DatabaseName
FROM DbsToMaintain
WHERE LastDateMaintained IS NULL
...[/code]
Go to Top of Page

chris_cs
Posting Yak Master

223 Posts

Posted - 2011-07-18 : 11:20:50
I can't believe it was that simple

That works perfectly now so thanks for your help!

Junior DBA learning the ropes
Go to Top of Page

russell
Pyro-ma-ni-yak

5072 Posts

Posted - 2011-07-18 : 11:37:44
Glad to help :)
Go to Top of Page
   

- Advertisement -