Technical Article

Set standard database options

,

This routine sets standardised database options. It is a common problem that database options differ from the site standard, especially in Development environments. Running this routine via a weekly SQL Agent job overcomes this problem.

To set standard options for all databases:

EXEC spSetDBOptions

To set standard options for a given database:

EXEC spSetDBOptions @dbname='Your_Database'

To generate code but make no changes, use the @process parameter. To seet debugging information, use the @debug parameter:

EXEC spSetDBOptions @process='N',@debug='Y'

The setting of individual options can be suppressed by using the @setopts, @setowner, @setsize parameters.

This routine will produce an appropriate message if an errors occurs. Use the following statement to add the message to SQL Server:

EXEC sp_addmessage 700000, 16, N'%ls'

USE DBA_Data
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[spSetDBOptions]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
  drop procedure [dbo].[spSetDBOptions]
GO

SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO

CREATE PROCEDURE [dbo].[spSetDBOptions] 
  @dbnamenvarchar(120) = N'%',-- List of database names to process
  @setoptschar(1) = 'Y',-- Set DB options
  @setownerchar(1) = 'Y',-- Set DB owner
  @setsizechar(1) = 'Y',-- Set DB size
  @debugchar(1) = 'N',-- Print debug information
  @processchar(1) = 'Y',-- Process commands
  @stopchar(1) = 'N'-- Stop if error encountered
AS BEGIN
--
-- spSetDBOptions Version V1.2 09May2007
--
-- Change History
-- V1.0 11Jan2007 Ed Vassie    Initial version
-- V1.1 21Apr2007 Ed Vassie Added DB Sizing
-- V1.2 09May2007 Ed Vassie Added @dbname parameter
--
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NOCOUNT ON
--
DECLARE @cmptleveltinyint
DECLARE @dbownernvarchar(60)
DECLARE @debug_labelnvarchar(60)
DECLARE @fnamenvarchar(60)
DECLARE @index    integer
DECLARE @instlevelinteger
DECLARE @sa_acntnvarchar(60)
DECLARE @sa_flagbit
DECLARE @sqlstringnvarchar(4000)
DECLARE @rcinteger
--
PRINT 'Setup DB Options for ' + @@SERVERNAME + ' at ' + Convert(char(20), Getdate(), 113)
--
-- Get Instance software level
SET @debug_label = 'SELECT @instlevel'
SELECT @instlevel = cmptlevel FROM master.dbo.sysdatabases WHERE name = 'master'
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
-- Get builtin system administration account name
SET @debug_label = 'SELECT @sa_acnt'
SELECT @sa_acnt = name FROM master..syslogins WHERE sid=1
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
-- Create work tables
SET @debug_label = 'CREATE TABLE #dblist'
CREATE TABLE #dblist (dbid int not null, name nvarchar(256) not null, cmptlevel tinyint, owner nvarchar(256))
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
SET @debug_label = 'CREATE TABLE #dbsize'
CREATE TABLE #dbsize (fileid integer, action bit, name nvarchar(512), sqlalter nvarchar(512))
SELECT @rc = @@error
IF @rc > 0 GOTO setrc
--
-- Build table of databases to be processed
SET @debug_label = 'INSERT INTO #dblist'
INSERT INTO #dblist SELECT dbid,name,cmptlevel,suser_sname(sid)
 FROM master..sysdatabases 
 WHERE HAS_DBACCESS(name) = 1
 AND name LIKE @dbname
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
IF @debug <> 'N' SELECT * FROM #dblist ORDER BY name
--
-- Declare database cursor dbline
SET @debug_label = 'DECLARE dbline CURSOR'
DECLARE dbline CURSOR FOR 
SELECT
  name,cmptlevel,owner
FROM #dblist ORDER BY name
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
-- Declare database cursor dbsize
SET @debug_label = 'DECLARE dbsize CURSOR'
DECLARE dbsize CURSOR FOR 
SELECT
  sqlalter, name
FROM #dbsize WHERE action = 1 ORDER BY fileid
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
SET @debug_label = 'OPEN dbline'
OPEN dbline
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
SET @debug_label = 'FIRST FETCH dbline'
FETCH dbline INTO @dbname,@cmptlevel,@dbowner
SELECT @rc = @@error
IF @rc > 0 GOTO setrc 
--
WHILE @@fetch_status <> -1
  BEGIN
  PRINT ' '
  PRINT 'Processing database ' + @dbname

  IF @setopts = 'Y'
    BEGIN
    -- Process database options

    IF @instlevel = 80 -- set options for database in SQL 2000 mode
      BEGIN
      IF @cmptlevel < @instlevel
        PRINT 'Invalid database compatibility level. Run "sp_dbcmptlevel ' + @dbname + ', ' + Cast(@cmptlevel as Char(2)) + '" then re-run this procedure'
      ELSE 
        BEGIN
        SET @debug_label = 'Setup DB option string'
        SET @sqlstring = 'ALTER DATABASE [' + @dbname + '] SET AUTO_CREATE_STATISTICS ON, AUTO_UPDATE_STATISTICS ON'
        IF @dbname <> 'tempdb' 
          BEGIN
          SET @sqlstring = @sqlstring + ', TORN_PAGE_DETECTION ON'
          IF @dbname <> 'master' 
            SET @sqlstring = @sqlstring + ', AUTO_CLOSE OFF, AUTO_SHRINK OFF'
          END
        SET @sqlstring = @sqlstring + ' WITH ROLLBACK IMMEDIATE'
        IF @debug <> 'N' PRINT 'SQL String:' + @sqlstring
        IF @process = 'Y' 
          BEGIN
          SET @debug_label = 'EXEC (@sqlstring) db options'
          PRINT 'Setting DB Options'
          EXEC (@sqlstring)
          SELECT @rc = @@error
          IF @rc > 0 
            BEGIN
            IF @stop <> 'N' GOTO setrc 
            SET @sqlstring = @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
            RAISERROR (700000,16,1,@sqlstring) WITH LOG,NOWAIT
            END 
          END
        ELSE 
          PRINT 'Bypassed ' + @sqlstring
        END
      END

    IF @instlevel = 90 -- set options for database in SQL 2005 mode
    BEGIN
    IF @cmptlevel < @instlevel
      PRINT 'Invalid database compatibility level. Run "sp_dbcmptlevel ' + @dbname + ', ' + Cast(@cmptlevel as Char(2)) + '" then re-run this procedure'
    ELSE 
      BEGIN
      SET @debug_label = 'Setup DB option string'
      SET @sqlstring = 'ALTER DATABASE [' + @dbname + '] SET AUTO_CREATE_STATISTICS ON, AUTO_UPDATE_STATISTICS ON, AUTO_UPDATE_STATISTICS_ASYNC ON, DATE_CORRELATION_OPTIMIZATION ON'
      IF @dbname <> 'tempdb' 
        BEGIN
        SET @sqlstring = @sqlstring + ', TORN_PAGE_DETECTION OFF, PAGE_VERIFY CHECKSUM'
        IF @dbname <> 'master' 
          SET @sqlstring = @sqlstring + ', AUTO_CLOSE OFF, AUTO_SHRINK OFF'
        END
      SET @sqlstring = @sqlstring + ' WITH ROLLBACK IMMEDIATE'
      IF @debug <> 'N' PRINT 'SQL String:' + @sqlstring
      IF @process = 'Y' 
        BEGIN
        SET @debug_label = 'EXEC (@sqlstring) DB options'
        PRINT 'Setting DB Options'
        EXEC (@sqlstring)
        SELECT @rc = @@error
        IF @rc > 0 
          BEGIN
          IF @stop <> 'N' GOTO setrc 
          SET @sqlstring = @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
          RAISERROR (700000,16,1,@sqlstring) WITH LOG,NOWAIT
          END 
        END
      ELSE 
        PRINT 'Bypassed ' + @sqlstring
      END
    END
  END 

  IF @setowner = 'Y'
   BEGIN
   -- Set DB owner name
   SELECT @sa_flag = sysadmin FROM master.dbo.syslogins WHERE name = @dbowner
   IF ((Charindex('\#',@dbowner) > 0) OR (Coalesce(@sa_flag, 0) = 1)) AND (@dbowner <> @sa_acnt) AND (Charindex(@dbname + ' ', 'master model tempdb ') = 0)
     BEGIN
     SET @debug_label = 'Setup DB owner string'
     SET @sqlstring = 'USE [' + @dbname +'];EXEC sp_changedbowner ''' + @sa_acnt + ''''
     IF @debug <> 'N' PRINT 'SQL String:' + @sqlstring
     IF @process = 'Y' 
       BEGIN
       SET @debug_label = 'EXEC (@sqlstring) sp_changedbowner'
       PRINT 'Changing DB owner from ' + @dbowner + ' to ' + @sa_acnt
       EXEC (@sqlstring)
       SELECT @rc = @@error
       IF @rc > 0 
         BEGIN
         IF @stop <> 'N' GOTO setrc 
         SET @sqlstring = @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
         RAISERROR (700000,16,1,@sqlstring) WITH LOG,NOWAIT
         END 
       END
     ELSE 
       PRINT 'Bypassed ' + @sqlstring
     END
   END 

  IF @setsize = 'Y'
    BEGIN
    -- Set DB size parameters
    --
    -- Prepare database size table
    SET @debug_label = 'Truncate table #dbsize'
    TRUNCATE TABLE #dbsize
    SELECT @rc = @@error
    IF @rc > 0 GOTO setrc 
    --
    -- Build table of database size alter statements
    SET @debug_label = 'Setup dbsize string'
    SET @sqlstring = 'INSERT INTO #dbsize SELECT fileid, action, name, sqlalter FROM (SELECT s.fileid,' +
       'CASE WHEN s.size < s.newsize THEN 1 WHEN s.growth <> s.newgrowth THEN 1 ELSE 0 END As action, s.name, ' + 
       '''ALTER DATABASE [' + RTrim(@dbname) + '] MODIFY FILE (NAME=['' + s.name + '']'' +' +
       'CASE WHEN s.size < s.newsize THEN '', SIZE = '' + Cast(s.newsize as varchar(50)) + '' MB'' ELSE '''' END + ' +
       'CASE WHEN s.growth <> s.newgrowth THEN '', FILEGROWTH = '' + Cast(s.newgrowth as varchar(50)) + '' MB'' ELSE '''' END + ' + 
       ''', MAXSIZE=UNLIMITED)'' As [sqlalter] ' +
     'FROM (SELECT fileid ,RTrim(f.name) As name ,(f.size / 128) As size ,CASE ' +
       'WHEN ((f.size / 128) <= 10) AND (f.groupid = 0) THEN (((((f.size - 1) / 128) / 5) * 5) + 5) ' +
       'WHEN (f.size / 128) <= 50 THEN (((((f.size - 1) / 128) / 10) * 10) + 10) ' +
       'WHEN (f.size / 128) <= 200 THEN (((((f.size - 1) / 128) / 50) * 50) + 50) ' +
       'WHEN (f.size / 128) <= 1000 THEN (((((f.size - 1) / 128) / 200) * 200) + 200) ' +
       'WHEN (f.size / 128) <= 10000 THEN (((((f.size - 1) / 128) / 500) * 500) + 500) ' +
       'WHEN (f.size / 128) <= 100000 THEN (((((f.size - 1) / 128) / 5000) * 5000) + 5000) ' +
       'ELSE (((((f.size - 1) / 128) / 100000) * 100000) + 100000) ' +
       'END AS newsize ,(f.growth / 128) As growth ,CASE ' +
       'WHEN (f.size / 128) <= 50 THEN 10 ' +
       'WHEN (f.size / 128) <= 200 THEN 50 ' +
       'WHEN (f.size / 128) <= 1000 THEN 200 ' +
       'WHEN (f.size / 128) <= 10000 THEN 500 ' +
       'WHEN (f.size / 128) <= 100000 THEN 5000 ' +
       'ELSE 100000 END AS newgrowth ' +
     'FROM [' + RTrim(@dbname) + '].dbo.sysfiles f ' +
       'WHERE f.groupid IN (SELECT m.groupid FROM [' + RTrim(@dbname) + '].dbo.sysfiles m GROUP BY m.groupid HAVING Count(*) = 1)) s) r'
    IF @debug <> 'N' PRINT 'SQL String:' + @sqlstring
    -- 
    SET @debug_label = 'EXEC (@sqlstring) insert #dbsize'
    EXEC (@sqlstring)
    SELECT @rc = @@error
    IF @debug <> 'N' SELECT * FROM #dbsize ORDER BY fileid
    IF @rc > 0 
      BEGIN
      IF @stop <> 'N' GOTO setrc 
      SET @sqlstring = @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
      RAISERROR (700000,16,1,@sqlstring) WITH LOG,NOWAIT
      END 
    --
    SET @debug_label = 'OPEN dbsize'
    OPEN dbsize
    SELECT @rc = @@error
    IF @rc > 0 GOTO setrc 
    --
    SET @debug_label = 'FIRST FETCH dbsize'
    FETCH dbsize INTO @sqlstring,@fname
    SELECT @rc = @@error
    IF @rc > 0 GOTO setrc 
    --
    WHILE @@fetch_status <> -1
      BEGIN

      PRINT 'Set DB file size: ' + @sqlstring
      IF @process = 'Y' 
        BEGIN
        SET @debug_label = 'EXEC (@sqlstring) Set size'
        EXEC (@sqlstring)
        SELECT @rc = @@error
        IF @rc > 0 
          BEGIN
          IF @stop <> 'N' GOTO setrc 
          SET @sqlstring = @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
          RAISERROR (700000,16,1,@sqlstring) WITH LOG,NOWAIT
          END 
        END
      ELSE 
        PRINT 'Bypassed ' + @sqlstring

      SET @debug_label = 'FETCH dbsize'
      FETCH dbsize INTO @sqlstring,@fname
      SELECT @rc = @@error
      IF @rc > 0 GOTO setrc 
      END

    SET @debug_label = 'CLOSE dbsize'
    CLOSE dbsize
    SELECT @rc = @@error
    IF @rc > 0 GOTO setrc
    END

  SET @debug_label = 'FETCH dbline'
  FETCH dbline INTO @dbname,@cmptlevel,@dbowner
  SELECT @rc = @@error
  IF @rc > 0 GOTO setrc 
  END
--
setrc:
IF @rc > 0 
  BEGIN
  SET @sqlstring = @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
  RAISERROR (700000,16,1,@sqlstring) WITH LOG,NOWAIT
  END
SET @debug_label = 'CLOSE dbline'
CLOSE dbline
SELECT @rc = @@error
IF @rc > 0 PRINT @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
SET @debug_label = 'DEALLOCATE dbline'
DEALLOCATE dbline
SELECT @rc = @@error
IF @rc > 0 PRINT @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
SET @debug_label = 'DROP TABLE #dblist'
DROP TABLE #dblist
SELECT @rc = @@error
IF @rc > 0 PRINT @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
SET @debug_label = 'DEALLOCATE dbsize'
DEALLOCATE dbsize
SELECT @rc = @@error
IF @rc > 0 PRINT @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
SET @debug_label = 'DROP TABLE #dbsize'
DROP TABLE #dbsize
SELECT @rc = @@error
IF @rc > 0 PRINT @debug_label + ' FAILED, ERROR=' + Cast(@rc As Varchar)
--
RETURN @rc
END

GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

Rate

4 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

4 (1)

You rated this post out of 5. Change rating