USE [master] GO BEGIN TRY -- must set database name, number of data files and data file size -- database name DECLARE @databaseName NVARCHAR(100) = 'some data base' -- number of data files DECLARE @numberDataFiles TINYINT = 2 -- normally should not have LESS then 2 data files -- size of data files DECLARE @ndfSize DECIMAL(6, 3) = 2 -- allowed sizes: 0.125, 0.25, 0.5, 1.0, 2.0, 3.0, 4.0 -- set to one to enable filestream DECLARE @withFileStream BIT = 0 -- allowed values 0 or 1 - default=0 (no filestream) -- if using database switching then set hasSwitch=1 -- uses database-switching and snapshot - default=FALSE - on TRUE will generate script for two databases (__00 & __01) plus snapshot DECLARE @hasSwitch BIT = 0 -- ensure ndf file size is allowed IF NOT (@ndfSize IN (0.125, 0.25, 0.5, 1.0, 2.0, 3.0, 4.0)) BEGIN DECLARE @x VARCHAR(10) = CAST(@ndfSize AS VARCHAR(10)) RAISERROR ('.ndf File Size of %s is NOT an allowed value for ndfSize - cannot continue! [allowed: 0.125, 0.25, 0.5, 1.0, 2.2, 3.0, 4.0]', 14, 2, @x); END -- trim and remove square brackets [] from databaseName SET @databaseName = LTRIM(RTRIM(REPLACE(REPLACE(@databaseName, '[', ''), ']', ''))) -- script vars DECLARE @s CHAR(4) = ' ' -- spacer for indents DECLARE @dataDir NVARCHAR(200) = ( SELECT PropertyValue FROM [master].dbo.fn_List_ServerProperties() WHERE PropertyName = 'Data_Directory' ) DECLARE @LogDir NVARCHAR(200) = ( SELECT PropertyValue FROM [master].dbo.fn_List_ServerProperties() WHERE PropertyName = 'Log_Directory' ) DECLARE @fsDir NVARCHAR(200) = ( SELECT PropertyValue FROM [master].dbo.fn_List_ServerProperties() WHERE PropertyName = 'Filestream_Directory' ) DECLARE @snapshotDir NVARCHAR(200) = ( SELECT PropertyValue FROM [master].dbo.fn_List_ServerProperties() WHERE PropertyName = 'Snapshot_Directory' ) DECLARE @gb INT = 1024 -- file size as string DECLARE @nSize NVARCHAR(10) = CAST(CAST((@gb * @ndfSize) AS INT) AS NVARCHAR(10)) + 'MB' -- file growth based on file size: if greater than 256MB (0.25) then 512MB else 128MB DECLARE @fileGrowth NVARCHAR(10) = CASE WHEN (@ndfSize > 0.25) THEN '512MB' ELSE '128MB' END -- table to hold all sql statements DECLARE @tbl TABLE (Tbl_PK INT IDENTITY (1, 1) NOT NULL, SqlString NVARCHAR(MAX) NOT NULL, ForSwitch BIT DEFAULT (1)) -- add USE MASTER to sqlTable INSERT INTO @tbl (SqlString) SELECT '' INSERT INTO @tbl (SqlString) SELECT '' INSERT INTO @tbl (SqlString) SELECT '/* create database ' + @databaseName + ' */' INSERT INTO @tbl (SqlString) SELECT 'USE [master]' INSERT INTO @tbl (SqlString) SELECT 'GO' INSERT INTO @tbl (SqlString) SELECT '' -- script test for existing DB INSERT INTO @tbl (SqlString) SELECT 'IF EXISTS ( SELECT * FROM sys.databases WHERE name = ''' + @databaseName + ''' )' INSERT INTO @tbl (SqlString) SELECT ' BEGIN' INSERT INTO @tbl (SqlString) SELECT @s + 'RAISERROR (''ERROR: Database [%s] already exists on this server - cannot continue!'', 10, 1, ''' + @databaseName + ''')' INSERT INTO @tbl (SqlString) SELECT ' END' -- script else create database INSERT INTO @tbl (SqlString) SELECT 'ELSE' INSERT INTO @tbl (SqlString) SELECT ' BEGIN' INSERT INTO @tbl (SqlString) SELECT '' INSERT INTO @tbl (SqlString) SELECT @s + 'CREATE DATABASE [' + @databaseName + ']' INSERT INTO @tbl (SqlString) SELECT @s + @s + 'ON PRIMARY' INSERT INTO @tbl (SqlString) SELECT @s + @s + @s + '(NAME = ' + @databaseName + '__primary, FILENAME = ''' + @dataDir + '\' + @databaseName + '__primary.mdf'', SIZE = 16MB, MAXSIZE = UNLIMITED, FILEGROWTH = 16MB),' INSERT INTO @tbl (SqlString) SELECT '' -- ndf files INSERT INTO @tbl (SqlString) SELECT @s + @s + 'FILEGROUP DATA DEFAULT' + @s + ' -- sizes -- 128MB -- 256MB -- 512MB' + ' -- ' + CAST(@gb AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 2 AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 3 AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 4 AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 5 AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 6 AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 7 AS NVARCHAR(10)) + 'MB' + ' -- ' + CAST(@gb * 8 AS NVARCHAR(10)) + 'MB' -- add data files for default filegroup "DATA" DECLARE @i INT = 1 WHILE @i <= @numberDataFiles BEGIN -- data file INSERT INTO @tbl (SqlString) SELECT @s + @s + @s + '(NAME = ' + @databaseName + '__data_' + CAST(@i AS NVARCHAR(10)) + ', FILENAME = ''' + @dataDir + '\' + @databaseName + '__data_' + CAST(@i AS NVARCHAR(10)) + '.ndf'',' + ' SIZE = ' + @nSize + ', MAXSIZE = UNLIMITED, FILEGROWTH = ' + @fileGrowth + ')' + CASE WHEN (@i < @numberDataFiles) THEN ',' ELSE '' END -- incremetn counter i SET @i += 1 END INSERT INTO @tbl (SqlString) SELECT '' -- filestream if needed IF @withFileStream = 0 BEGIN INSERT INTO @tbl (SqlString) SELECT @s + @s + '-- Un-Comment if FILESTREAM is needed' END INSERT INTO @tbl (SqlString) SELECT @s + @s + CASE WHEN @withFileStream = 0 THEN '--' ELSE '' END + ',' INSERT INTO @tbl (SqlString) SELECT @s + @s + CASE WHEN @withFileStream = 0 THEN '--' ELSE '' END + 'FILEGROUP [FILESTREAM] CONTAINS FILESTREAM DEFAULT' INSERT INTO @tbl (SqlString) SELECT @s + @s + CASE WHEN @withFileStream = 0 THEN '--' ELSE '' END + @s + '(NAME = ' + @databaseName + '__fs, FILENAME = ''' + @fsDir + '\' + @databaseName + '__fs'')' INSERT INTO @tbl (SqlString) SELECT '' -- log file INSERT INTO @tbl (SqlString) SELECT @s + @s + 'LOG ON' INSERT INTO @tbl (SqlString) SELECT @s + @s + @s + '(NAME = ' + @databaseName + '__log,' + ' FILENAME = ''' + @logDir + '\' + @databaseName + '__log.ldf'',' + ' SIZE = ' + @nSize + ',' + ' MAXSIZE = UNLIMITED,' + ' FILEGROWTH = ' + @fileGrowth + ')' INSERT INTO @tbl (SqlString) SELECT '' -- set collation to CI/AS INSERT INTO @tbl (SqlString) SELECT @s + @s + 'COLLATE Latin1_General_CI_AS' INSERT INTO @tbl (SqlString) SELECT ' END' -- print results INSERT INTO @tbl (SqlString) SELECT 'PRINT ''DB [' + @databaseName + '] created''' INSERT INTO @tbl (SqlString) SELECT 'GO' INSERT INTO @tbl (SqlString) SELECT '' -- set dbOwner to sa INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '-- set dbOwner on created databases', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + ']', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'EXECUTE sp_changedbowner @loginame = ''sa'', @map = false', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 IF (@hasSwitch = 1) BEGIN INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [' + @databaseName + '__01]', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'EXECUTE sp_changedbowner @loginame = ''sa'', @map = false', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 END -- set RecoveryModel to SIMPLE --'ALTER DATABASE [' + Name + '] SET RECOVERY SIMPLE WITH NO_WAIT' INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '-- set RecoveryModel to SIMPLE on created databases', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + ']', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'ALTER DATABASE [' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + '] SET RECOVERY SIMPLE WITH NO_WAIT', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 IF (@hasSwitch = 1) BEGIN INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [' + @databaseName + '__01]', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'ALTER DATABASE [' + @databaseName + '__01] SET RECOVERY SIMPLE WITH NO_WAIT', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 END -- set compatibility to SQL2017 (140) --'ALTER DATABASE [' + Name + '] SET COMPATIBILITY_LEVEL = 140' INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '-- set compatibility to SQL2017 (140) on created databases', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + ']', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'ALTER DATABASE [' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + '] SET COMPATIBILITY_LEVEL = 140', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 IF (@hasSwitch = 1) BEGIN INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [' + @databaseName + '__01]', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'ALTER DATABASE [' + @databaseName + '__01] SET COMPATIBILITY_LEVEL = 140', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 END -- snapshot if needed INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '/* script for ' + @databaseName + ' snapshot' + CASE WHEN (@hasSwitch = 1) THEN ' */' ELSE '' END, 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [master]', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'IF EXISTS (SELECT name FROM sys.databases WHERE name = ''' + @databaseName + ''')', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT ' BEGIN', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT @s + 'DROP DATABASE ' + @databaseName, 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT ' END', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'CREATE DATABASE ' + @databaseName, 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT @s + 'ON', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT @s + @s + '(NAME = ' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + '__primary, FILENAME = ''' + @snapshotDir + '\' + @databaseName + '.ss''),', 0 -- add snapshot data file for each datafile SET @i = 1 WHILE @i <= @numberDataFiles BEGIN -- data file INSERT INTO @tbl (SqlString, ForSwitch) SELECT @s + @s + '(NAME = ' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END + '__data_' + CAST(@i AS NVARCHAR(10)) + ',' + ' FILENAME = ''' + @snapshotDir + '\' + @databaseName + '_' + CAST(@i AS NVARCHAR(10)) + '.ss'')' + CASE WHEN (@i < @numberDataFiles) THEN ',' ELSE '' END, 0 -- incremetn counter i SET @i += 1 END -- finish snapshot INSERT INTO @tbl (SqlString, ForSwitch) SELECT @s + 'AS SNAPSHOT OF ' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN '__00' ELSE '' END, 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 -- print switch/snapshot results INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'PRINT ''SNAPSHOT [' + @databaseName + '] created''', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 -- end comment if not switching IF (@hasSwitch = 0) BEGIN INSERT INTO @tbl (SqlString, ForSwitch) SELECT '*/', 0 END -- print results INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'USE [master]', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'GO', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '/* generated script for:', 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT 'CREATE DATABASE ' + @databaseName + CASE WHEN (@hasSwitch = 1) THEN ' __00 __01 & snapshot' ELSE '' END, 0 INSERT INTO @tbl (SqlString, ForSwitch) SELECT '*/', 0 -- return all SQL strings - if hasSwitch=TRUE then select forSwitch records twice (with each name) else only select once IF (@hasSwitch = 0) BEGIN SELECT SqlString FROM @tbl ORDER BY Tbl_PK END ELSE BEGIN SELECT SqlString FROM ( -- for db __00 SELECT REPLACE(SqlString, @databaseName, @databaseName + '__00') AS SqlString, 1 AS SortOrder, Tbl_PK FROM @tbl WHERE ForSwitch = 1 -- for db __00 UNION ALL -- for db __01 SELECT REPLACE(SqlString, @databaseName, @databaseName + '__01') AS SqlString, 2 AS SortOrder, Tbl_PK FROM @tbl WHERE ForSwitch = 1 -- for db __01 UNION ALL -- for snapshot SELECT SqlString, 3 AS SortOrder, Tbl_PK FROM @tbl WHERE ForSwitch = 0 -- for snapshot ) s ORDER BY SortOrder, Tbl_PK END ------ return file directories for proofing ----SELECT @dataDir AS Data_Directory, @LogDir AS Log_Directory, @fsDir AS Filestream_Directory, @snapshotDir AS Snapshot_Directory END TRY BEGIN CATCH EXECUTE [master].dbo.sp_RethrowError END CATCH