Thursday, October 15, 2015

How to add ReportViewer Control to Visual Studio 2012 Express

ASP.Net MVC Views in fact are ASP.Net web forms without View State. To incorporate SSRS reports, a web form control named Report Viewer is needed. Since Report Viewer is a web form control, you need to add ASP.Net web form to host the Report Viewer control. You can easily add Web Form in ASP.Net MVC project for this purpose.

Report Viewer is under Visual Studio Toolbox. If you can't find the control, following steps would help you to install it.

First, install the 2012 Report Viewer Runtime, which is a free download on Microsoft's website:
http://www.microsoft.com/en-us/downl....aspx?id=35747

Second, open Visual Studio 2012 Express, go to Tools, and click Choose Toolbox Items.

Third, scroll down the list, you would find 2 ReportViewer control, one is for WebForms,  and the other is for WebForms. Both of them are version 10.0.0.0. You need to click on the Browse button to find the version 11.0.0.0 you just installed.

Navigate to the ReportViewer Runtime you just installed and select Microsoft.ReportViewer.WebForms.dll.

Now Report Viewer control has been added into Toolbox.

Source:
https://www.nuget.org/packages/Microsoft.ReportViewer/
http://stackoverflow.com/questions/6144513/how-can-i-use-a-reportviewer-control-in-an-asp-net-mvc-3-razor-view
http://blogs.msdn.com/b/sajoshi/archive/2010/06/16/asp-net-mvc-handling-ssrs-reports-with-reportviewer-part-ii-deployment-challenges.aspx
http://forums.asp.net/t/1963101.aspx?SSRS+Report+Viewer+in+MVC4
http://dotnetspeak.com/2012/02/using-ssrs-in-asp-net-mvc-application
http://stackoverflow.com/questions/6144513/how-can-i-use-a-reportviewer-control-in-an-asp-net-mvc-3-razor-view
http://stackoverflow.com/questions/15208437/how-can-i-use-a-reportviewer-control-with-razor
https://www.packtpub.com/books/content/mixing-aspnet-webforms-and-aspnet-mvc

https://msdn.microsoft.com/en-us/library/ms251661.aspx

http://www.vbforums.com/showthread.php?717175-How-to-use-Report-Viewer-with-Visual-Studio-2012-Express

http://www.codemag.com/article/1009061http://www.codemag.com/article/1011131

http://blogs.msdn.com/b/sajoshi/archive/2010/06/16/asp-net-mvc-handling-ssrs-reports-with-reportviewer-part-i.aspx

Friday, October 9, 2015

Applying Windows command and SQLCMD to execute sql script

SQL Server has one very useful tool named sqlcmd which can execute pre-defined sql script file. You can use sqlcmd along with windows batch command to add parameters to your sql script so that it can be used more flexible.

Firstly, let's see the pre-defined sql script, which was used to create one database. For more detailed information about the script, you can read from here. Note the script has been changed to be run under sqlcmd as the script can accept 4 sqlcmd parameters named
$(varDropDB), $(varDBName), $(varDBFileDirectory), @DBBAKFileDirectory.

Note there are single quotas while referencing those 4 parameters. This is because the sqlcmd just simply replaces those 4 parameters with their values like windows command, if you missed single quota, executing the script with sqlcmd would result mistake.
DECLARE @DeleteExistingDB VARCHAR(10)
DECLARE @DBName VARCHAR(20)
DECLARE @DBFileDirectory VARCHAR(100)
DECLARE @DBBAKFileDirectory VARCHAR(100)
DECLARE @SQL_SCRIPT VARCHAR(MAX)

DECLARE @NewUser VARCHAR(20)
DECLARE @NewUserPassword VARCHAR(20)

SET @NewUser = '$(varNewUser)' -- 'test'
SET @NewUserPassword = '$(varNewUserPassword)' -- 'Test123'

SET @DeleteExistingDB = '$(varDropDB)' -- 'TRUE'
SET @DBName = '$(varDBName)' -- 'TestDB'
SET @DBFileDirectory = '$(varDBFileDirectory)'  -- 'D:\Data'
SET @DBBAKFileDirectory  = '$(varDBBAKFileDirectory)'  -- 'D:\Data\Backup'

IF Exists(Select * From sys.databases Where name = @DBName)  AND @DeleteExistingDB = 'TRUE'
BEGIN
    USE [master]
    /* BACKUP DATABASE */
    SET @SQL_SCRIPT = N'BACKUP DATABASE {{DWDBNAME}} TO DISK = N' + CHAR(39) + @DBBAKFileDirectory  
        + '\{{DWDBNAME}}_' + CONVERT(char(8), GetDate(),112)  + '_bySSIS.bak' + CHAR(39) 
        + ' WITH NOFORMAT, SKIP, NOREWIND, NOUNLOAD,  STATS = 10' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @DBName) 
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)

    /* Delete Database Backup and Restore History from MSDB System Database */
    SET @SQL_SCRIPT = 'EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = ''' + @DBName + ''''
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)

    /* Query to Get Exclusive Access of SQL Server Database before Dropping the Database */
    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)

    /*Drop the DB*/
    SET @SQL_SCRIPT = 'DROP DATABASE ' + @DBName
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)
END

IF NOT Exists(Select * From sys.databases Where name = @DBName)
BEGIN
    /* Create New Genuina Data Mart DB */
    SET @SQL_SCRIPT = 
    'CREATE DATABASE {{DWDBNAME}} CONTAINMENT = NONE ON  PRIMARY 
    ( 
        NAME = ' + CHAR(39) + '{{DWDBNAME}}' collate Latin1_General_CI_AS + CHAR(39) + ', FILENAME = N' + CHAR(39) + @DBFileDirectory 
             + '\{{DWDBNAME}}.mdf' + CHAR(39) + ', SIZE = 262144KB , MAXSIZE = UNLIMITED, FILEGROWTH = 12800KB 
    )
    LOG ON 
    ( 
        NAME = N'  + CHAR(39) + '{{DWDBNAME}}_log' + CHAR(39) + ', FILENAME = N' + CHAR(39) + @DBFileDirectory 
             + '\{{DWDBNAME}}_log.ldf' + CHAR(39) + ', SIZE = 65536KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%
    )' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT,  '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @DBName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET COMPATIBILITY_LEVEL = 90;'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 
    'IF (1 = FULLTEXTSERVICEPROPERTY(' + CHAR(39) + 'IsFullTextInstalled' + CHAR(39) +'))
    BEGIN
        EXEC ' + @DBName + '.[dbo].[sp_fulltext_database] @action = ' + CHAR(39) + 'enable' + CHAR(39) + '
    END'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET ANSI_NULL_DEFAULT OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET ANSI_NULLS OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET ANSI_PADDING OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET ANSI_WARNINGS OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)
 
    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET ARITHABORT OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET AUTO_CLOSE OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET AUTO_CREATE_STATISTICS ON'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET AUTO_SHRINK ON'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET AUTO_UPDATE_STATISTICS ON'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET CURSOR_CLOSE_ON_COMMIT OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET CURSOR_DEFAULT  GLOBAL'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET CONCAT_NULL_YIELDS_NULL OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET NUMERIC_ROUNDABORT OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET QUOTED_IDENTIFIER OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET RECURSIVE_TRIGGERS OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET  DISABLE_BROKER'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET AUTO_UPDATE_STATISTICS_ASYNC ON'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET DATE_CORRELATION_OPTIMIZATION OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET TRUSTWORTHY OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET ALLOW_SNAPSHOT_ISOLATION OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET PARAMETERIZATION SIMPLE'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET READ_COMMITTED_SNAPSHOT OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET HONOR_BROKER_PRIORITY OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET RECOVERY SIMPLE'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET  MULTI_USER'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET PAGE_VERIFY TORN_PAGE_DETECTION'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET DB_CHAINING OFF'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET TARGET_RECOVERY_TIME = 0 SECONDS'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE ' + @DBName + ' SET  READ_WRITE'
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)
END

-- Create a user with a password from parameter
IF  EXISTS (SELECT * FROM sys.database_principals WHERE name = @NewUser)
BEGIN
    EXEC sp_dropuser @NewUser
END 

IF Exists (SELECT loginname FROM master.dbo.syslogins WHERE name = @NewUser)
BEGIN
    SET @SQL_SCRIPT = 'DROP LOGIN  [' + @NewUser + ']'
    -- SELECT  @SQL_SCRIPT
    EXEC (@SQL_SCRIPT)
END

SET @SQL_SCRIPT = 'CREATE LOGIN [' + @NewUser + '] WITH PASSWORD=''' + @NewUserPassword +''''
-- SELECT  @SQL_SCRIPT
EXEC (@SQL_SCRIPT)
 
SET @SQL_SCRIPT =  'USE ' + @DBName + '; CREATE USER [' + @NewUser + '] FOR LOGIN [' + @NewUser + '];'
-- SELECT  @SQL_SCRIPT
EXEC (@SQL_SCRIPT)

SET @SQL_SCRIPT = 'USE ' + @DBName + '; GRANT SELECT TO [' + @NewUser +'];'
-- SELECT  @SQL_SCRIPT
EXEC (@SQL_SCRIPT)

GO
Save above sql script as create_database.sql.

Next let's check the windows command which would load sqlcmd with parameters.

We want our windows command accepting parameters as well to make it flexible. Here %1 to %7 referring windows command parameters.
Also 3 sqlcmd parameters are applied here: -v means defining parameters used for sql script, -S means to connect the database server with server name or IP address, -i means executing the sql script file we pre-defined.
@ECHO OFF
IF [%1]==[/?] GOTO HELP
IF [%1]=="" GOTO NOENOUGHPARAMETERS
IF [%2]=="" GOTO NOENOUGHPARAMETERS
IF [%3]=="" GOTO NOENOUGHPARAMETERS
IF [%4]=="" GOTO NOENOUGHPARAMETERS
IF [%5]=="" GOTO NOENOUGHPARAMETERS
IF [%6]=="" GOTO NOENOUGHPARAMETERS
SET db_name="%1"
ECHO db_name=%db_name%
SET db_file_directory="%2"
ECHO db_file_directory=%db_file_directory%
SET db_bakfile_directory="%3"
ECHO db_bakfile_directory=%db_bakfile_directory%
SET user_name="%4"
ECHO user_name=%user_name%
SET user_password="%5"
ECHO user_password=%user_password%
SET server_name=%6
ECHO server_name=%server_name%
IF "%7"=="" (
    SET server_port=1433
) ELSE (
    SET server_port=%7
)
SET server_name=%server_name%,%server_port%
ECHO server_name=%server_name%

SET PATH=%PATH%; C:\Program Files\Microsoft SQL Server\110\Tools\Binn

sqlcmd -v varDropDB=TRUE  varDBName=%db_name%  varDBFileDirectory=%db_file_directory%  varDBBAKFileDirectory=%db_bakfile_directory%  varNewUser=%user_name% varNewUserPassword=%user_password%  -S %server_name% -i create_database.sql
ECHO Database %db_name% has created successfully.
GOTO DONE

:NOENOUGHPARAMETERS
ECHO You need at least 6 Parameters to finish the task
GOTO HELP

:HELP
ECHO This batch file is used to create Database, it applied sqlcmd which installed under the directory C:\Program Files\Microsoft SQL Server\110\Tools\Binn
ECHO This batch file required at least 6 parameters, if the 7th parameter, Server Port Number, is missing, a default port number 1433 would be used instead
ECHO Usage: install_dm_database DBName DBFileDirectory DBBakFileDirectory NewUsername NewUserPassword ServerName ServerPortNumber
ECHO Example: install_database.bat TestDB B:\Data B:\Data\Backup test Test123 192.168.99.22 1433
:DONE

Create SQL Script by Excel

As a database developer, you always need to create sql script to change data for tables during a common database maintenance process. Writing such script could be very tedious as many columns contains fixed or changed values which have special rules. Here applying Excel to create those script would be very helpful. Let's firstly investigate following sql script code created by Excel.

INSERT INTO #DayNameTable([DayNumberOFWeek],[EnglishDayNameOfWeek],[SpanishDayNameOfWeek],[FrenchDayNameOfWeek]) values
    (1,'Sunday','Domingo','Dimanche'),
    (2,'Monday','Lunes','Lundi'),
    (3,'Tuesday','Martes','Mardi'),
    (4,'Wednesday','Miércoles','Mercredi'),
    (5,'Thursday','Jueves','Jeudi'),
    (6,'Friday','Viernes','Vendredi'),
    (7,'Saturday','Sábado','Samedi');
You can use Excel string function to create above script very easily based on table data. Following is the data list abstracted from original table, you can copy/paste from your query result to Excel directly.

DayNumberOFWeek EnglishDayNameOfWeek SpanishDayNameOfWeek FrenchDayNameOfWeek
1 Sunday Domingo Dimanche
2 Monday Lunes Lundi
3 Tuesday Martes Mardi
4 Wednesday Miércoles Mercredi
5 Thursday Jueves Jeudi
6 Friday Viernes Vendredi
7 Saturday Sábado Samedi

The Excel expression to create above sql script would be :

=IF(NOT(ISBLANK(A2)),IF(A2=1, CONCATENATE("Insert into dbo.DImDate('DayNumberOFWeek','EnglishDayNameOfWeek','SpanishDayNameOfWeek','FrenchDayNameOfWeek') values(",A2,",'",B2,"','",C2,"','",D2,"'),"), CONCATENATE("(",A2,",'",B2,"','",C2,"','",D2,"');")))
It would check if the first row of column DayNumberOFWeek is empty, if not, it creates insert script based on the row data. Note when creating the insert script, for the 1st row, it will create full insert script with all available column name list and all column values; for the following rows, it just creates all column values.

After it's done, you just change the last comma to semi colon, and then you can applying the final sql script to your database directly.

Tuesday, October 6, 2015

How to deploy your SSIS packages

After you finished your SSIS packages and successfully test them, you want to deploy those packages to SQL Server and want to run the package on your SQL Server.

The first thing you need to do is to create one Integration Service Catalog, which will contain all deployed SSIS packages. Each SQL Server instance would have only one Catalog.

Open SQL Server Management Studio, Right click on Integration Services Catalogs, and choose Create Catalog, the Create Catalog Pop window will appear.


Enter catalog database name, encryption password, and choose if you want to run the Catalog.startup store procedure every time the SQL Server instance starts. The Catalog.startup store procedure would fix the status of catalog packages if these packages were executing while SQL Server went down.


After you created the Catalog, you can create one folder under it to store the deployed packages. Just right click on the Catalog Name, and choose "Create Folder".


Enter the folder name.


Under the newly created folder, there are 2 pre-defined folders: one is "Project", the other would be "Environments".


Now go back to your SSIS project, right click on your SSIS project name in BIDS, choose "Deploy",
following Project Deployment wizard will appear:


Fill the server name, and click on "Next" and then click on "Deploy".

If you don't have the required privilege to view the server, you can't deploy by this method. However, you can go to the bin folder of your SSIS project, copy the compiled SSIS project file xxx.ispac to the server manually and deploy the package on the server.

On your SQL Server, run SSMS, and choose the SSIS Catalog you just created, right click on the "Projects" directory, click on "Deploy Project". The SSIS package deployment wizard appeared.


Choose the xxx.ispac file you just copied to the server, and click on "Next".


The package has been deployed successfully. You can right click on Package.dtsx and choose "Execute" to run the package.


Source:
https://www.simple-talk.com/sql/ssis/ssis-2012-projects-setup,-project-creation-and-deployment/

How to change SSIS OLEDB Destination Settings to improve performance

There are many OLEDB Settings which can affact package performance:
  • Data Access Mode - This setting provides the 'fast load' option which internally uses a BULK INSERT statement for uploading data into the destination table instead of a simple INSERT statement (for each single row) as in the case for other options. So unless you have a reason for changing it, don't change this default value of fast load. If you select the 'fast load' option, there are also a couple of other settings which you can use as discussed below.
  • Keep Identity - By default this setting is unchecked which means the destination table (if it has an identity column) will create identity values on its own. If you check this setting, the dataflow engine will ensure that the source identity values are preserved and same value is inserted into the destination table.
  • Keep Nulls - Again by default this setting is unchecked which means default value will be inserted (if the default constraint is defined on the target column) during insert into the destination table if NULL value is coming from the source for that particular column. If you check this option then default constraint on the destination table's column will be ignored and preserved NULL of the source column will be inserted into the destination.
  • Table Lock - By default this setting is checked and the recommendation is to let it be checked unless the same table is being used by some other process at same time. It specifies a table lock will be acquired on the destination table instead of acquiring multiple row level locks, which could turn into lock escalation problems.
  • Check Constraints - Again by default this setting is checked and recommendation is to un-check it if you are sure that the incoming data is not going to violate constraints of the destination table. This setting specifies that the dataflow pipeline engine will validate the incoming data against the constraints of target table. If you un-check this option it will improve the performance of the data load.=
Source: https://www.mssqltips.com/sqlservertip/1840/sql-server-integration-services-ssis-best-practices/

Monday, October 5, 2015

Applying Dynamic SQL to Create Database and DimDate Dimension Table for SQL Server

When we write sql script, we want those code can be applied for different databases. We would prefer to define a sql variable named @dbname, and then apply the name to define a database we want to create. This is the Dynamic SQL Programming. For mysql, it's straight forward, however, for SQL Server, there are some issues we need to consider.
  • First, you can't apply the defined sql variable @dbName for USE statement to change the database.
  • Second, for some sql statement, such as Create Function/Trigger, SQL Server has limitation that these statements should be the only statement for the SQL Script batch. So you need to put GO before those statements. But applying GO will clear up all sql script variables you defined before those statements. 
For resolve those issues, we need to use Exec and sp_executesql command.

Following script will be used to create a database with the name defined as @TestDWName. It will check if the database exists, if it exists, it will backup the database, and then drop the database, and finally it will create the database.

The script used Exec only.
DECLARE @DeleteExistingDB VARCHAR(10)
DECLARE @TestDWName VARCHAR(20)
DECLARE @TestDWFileDirectory VARCHAR(100)
DECLARE @TestDWBAKFileDirectory VARCHAR(100)
DECLARE @SQL_SCRIPT VARCHAR(MAX)

SET @DeleteExistingDB = 'TRUE'
SET @TestDWName = 'test'
SET @TestDWFileDirectory =  'D:\Data\DW_DEV'
SET @TestDWBAKFileDirectory  =  'D:\Data\DW_DEV\Backup'

IF Exists(Select * From sys.databases Where name = @TestDWName)  AND @DeleteExistingDB = 'TRUE'
BEGIN
    USE [master]
    /* BACKUP DATABASE */
    SET @SQL_SCRIPT = N'BACKUP DATABASE {{DWDBNAME}} TO DISK = N' + CHAR(39) + @TestDWBAKFileDirectory
    + '\{{DWDBNAME}}_' + CONVERT(char(8), GetDate(),112)  + '_bySSIS.bak' + CHAR(39)
    + ' WITH NOFORMAT, SKIP, NOREWIND, NOUNLOAD,  STATS = 10' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)

    /* Delete Database Backup and Restore History from MSDB System Database */
    SET @SQL_SCRIPT = 'EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = {{DWDBNAME}}' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  CHAR(39) + @TestDWName collate Latin1_General_CI_AS + CHAR(39))
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)

    /* Query to Get Exclusive Access of SQL Server Database before Dropping the Database */
    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET SINGLE_USER WITH ROLLBACK IMMEDIATE' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)

    /*Drop the DB*/
    SET @SQL_SCRIPT = 'DROP DATABASE {{DWDBNAME}}' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT collate Latin1_General_CI_AS
    EXECUTE (@SQL_SCRIPT)
END

IF NOT Exists(Select * From sys.databases Where name = @TestDWName)
BEGIN
    /* Create New Genuina Data Warehouse */
    SET @SQL_SCRIPT =
    'CREATE DATABASE {{DWDBNAME}} CONTAINMENT = NONE ON  PRIMARY
    (
    NAME = ' + CHAR(39) + '{{DWDBNAME}}' collate Latin1_General_CI_AS + CHAR(39) + ', FILENAME = N' + CHAR(39) + @TestDWFileDirectory
    + '\{{DWDBNAME}}.mdf' + CHAR(39) + ', SIZE = 134646KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB
    )
    LOG ON
    (
    NAME = N'  + CHAR(39) + '{{DWDBNAME}}_log' + CHAR(39) + ', FILENAME = N' + CHAR(39) + @TestDWFileDirectory
    + '\{{DWDBNAME}}_log.ldf' + CHAR(39) + ', SIZE = 3840KB , MAXSIZE = 2048GB , FILEGROWTH = 10%
    )' collate Latin1_General_CI_AS
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT,  '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET COMPATIBILITY_LEVEL = 90;'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT =
    'IF (1 = FULLTEXTSERVICEPROPERTY(' + CHAR(39) + 'IsFullTextInstalled' + CHAR(39) +'))
    BEGIN
    EXEC {{DWDBNAME}}.[dbo].[sp_fulltext_database] @action = ' + CHAR(39) + 'enable' + CHAR(39) + '
    END'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT,  '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET ANSI_NULL_DEFAULT OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET ANSI_NULLS OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)
    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET ANSI_PADDING OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS ,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET ANSI_WARNINGS OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET ARITHABORT OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET AUTO_CLOSE OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET AUTO_CREATE_STATISTICS ON'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET AUTO_SHRINK ON'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET AUTO_UPDATE_STATISTICS ON'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET CURSOR_CLOSE_ON_COMMIT OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET CURSOR_DEFAULT  GLOBAL'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET CONCAT_NULL_YIELDS_NULL OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET NUMERIC_ROUNDABORT OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET QUOTED_IDENTIFIER OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET RECURSIVE_TRIGGERS OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET  DISABLE_BROKER'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET AUTO_UPDATE_STATISTICS_ASYNC ON'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET DATE_CORRELATION_OPTIMIZATION OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET TRUSTWORTHY OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET ALLOW_SNAPSHOT_ISOLATION OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET PARAMETERIZATION SIMPLE'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET READ_COMMITTED_SNAPSHOT OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET HONOR_BROKER_PRIORITY OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET RECOVERY SIMPLE'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET  MULTI_USER'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET PAGE_VERIFY TORN_PAGE_DETECTION'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET DB_CHAINING OFF'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET TARGET_RECOVERY_TIME = 0 SECONDS'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)

    SET @SQL_SCRIPT = 'ALTER DATABASE {{DWDBNAME}} SET  READ_WRITE'
    SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{{DWDBNAME}}' collate Latin1_General_CI_AS,  @TestDWName)
    -- SELECT @SQL_SCRIPT
    EXECUTE (@SQL_SCRIPT)
END
After we created the database, we want to create one very useful dimension table - DimDate. This table is from Microsoft AdventureWorksDW2012. We will create the table within the database we created above. The table has following structure:
    SET @SQL_SCRIPT  = 'CREATE TABLE ' + @TestDWName + '.dbo.[DimDate](
        [DateKey] [int] NOT NULL,
        [FullDateAlternateKey] [date] NOT NULL,
        [DayNumberOfWeek] [tinyint] NOT NULL,
        [EnglishDayNameOfWeek] [NVARCHAR](10) NOT NULL,
        [SpanishDayNameOfWeek] [NVARCHAR](10) NOT NULL,
        [FrenchDayNameOfWeek]  [NVARCHAR](10) NOT NULL,
        [DayNumberOfMonth] [tinyint] NOT NULL,
        [DayNumberOfYear]  [smallint] NOT NULL,
        [WeekNumberOfYear] [tinyint] NOT NULL,
        [EnglishMonthName] [NVARCHAR](10) NOT NULL,
        [SpanishMonthName] [NVARCHAR](10) NOT NULL,
        [FrenchMonthName]  [NVARCHAR](10) NOT NULL,
        [MonthNumberOfYear] [tinyint] NOT NULL,
        [CalendarQuarter]  [tinyint] NOT NULL,
        [CalendarYear] [smallint] NOT NULL,
        [CalendarSemester] [tinyint] NOT NULL,
        [FiscalQuarter] [tinyint] NOT NULL,
        [FiscalYear] [smallint] NOT NULL,
        [FiscalSemester] [tinyint] NOT NULL,
        CONSTRAINT [PK_DimDate_DateKey] PRIMARY KEY CLUSTERED
        (
        [DateKey] ASC
        )
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
        CONSTRAINT [AK_DimDate_FullDateAlternateKey] UNIQUE NONCLUSTERED
        (
        [FullDateAlternateKey] ASC
        )
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        ) ON [PRIMARY]'
Firstly, we need to check if the table has already existed. We applied sp_executesql instead of Exec above as we want to get return value from the dynamic sql.
SET @SQL_SCRIPT  = 'SELECT @SQLResult = 1 FROM ' + @TestDWName + '.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE=''BASE TABLE'' AND TABLE_NAME=''DimDate'''
SET @ParamDefinition = '@SQLResult AS tinyint Output'
EXEC sp_executesql @SQL_SCRIPT , @ParamDefinition, @SQLResult Output
For  sp_executesql, it more likes a function, which means it doesn't know any sql variables which pre-defined outside the script. In addition, if you applied USE statement inside the sp_executesql script to change the database, after the execution, the database will be changed back, thus, for following dynamic script, you need to apply USE statement again to change the database.

We then create the table and would like to create a user defined function to be used latter. Remember I said for Create Function script, SQL Server want them to be the only statement in the sql script batch. In addition, we can't add database name for Create Function statement. So to create the function within the desired database name, we need to apply USE statement to switch to the desired database. This two issues seemed to contradict with each other. But applying nested dynamic sql script can resolve this 2 issues both. Let's see the code:
SET @SQL_SCRIPT2 = 'USE ' + @TestDWName + '; EXEC sp_executesql N''' + @SQL_SCRIPT + '''';
-- SELECT @SQL_SCRIPT2
EXEC(@SQL_SCRIPT2);
Here the sql variable @SQL_SCRIPT2 contains USE statement to change the database, and then it contains another EXEC sp_executesql to execute   which is the real sql script to create the function.  After the function created, we need to create temp tables for loading the date. Note here the temp table is used instead of table variable. SQL Server do have table variable type, and we can use the table type to feed  sp_executesql, however, remember all dynamic script loading by  sp_executesql would not know those pre-defined table variable type. So once again, nested dynamic trick should be applied here, and this will increase the complexity greatly. For temp table, you just create them and after the usage, you drop them. You don't even to switch database as all temp tables are stored at tempdb . 
-- CREATE table #BogusTable
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#BogusTable'))
BEGIN
    DROP TABLE #BogusTable -- drop the temp table
END
CREATE TABLE #BogusTable(PK TINYINT);
INSERT INTO #BogusTable SELECT 1
Following code is the complete version of creating DimDate dimension table: 
DECLARE @DeleteExistingTable As NVARCHAR(10)
DECLARE @TestDWName   As NVARCHAR(20)
-- This is the start and end date ranges to populate the DimDate
DECLARE @FromDate     AS  NVARCHAR(10)
DECLARE @ThruDate     AS  NVARCHAR(10)

DECLARE @SQL_SCRIPT   AS NVARCHAR(MAX)
DECLARE @SQL_SCRIPT2  AS NVARCHAR(MAX)
DECLARE @ParamDefinition AS NVARCHAR(200)
DECLARE @SQLResult    AS tinyint = 0

SET @DeleteExistingTable = 'TRUE'
SET @TestDWName   = 'Test'
SET @FromDate =  '2010-01-01'
SET @ThruDate =  '2015-12-31'

SET @SQL_SCRIPT  = 'SELECT @SQLResult = 1 FROM ' + @TestDWName + '.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE=''BASE TABLE'' AND TABLE_NAME=''DimDate'''
SET @ParamDefinition = '@SQLResult AS tinyint Output'
EXEC sp_executesql @SQL_SCRIPT , @ParamDefinition, @SQLResult Output

-- Create DimDate table
IF @SQLResult = 1 AND @DeleteExistingTable = 'TRUE'
BEGIN
    SET @SQL_SCRIPT  = 'DROP Table ' + @TestDWName + '.dbo.DimDate'
    -- SELECT @SQL_SCRIPT
    EXEC (@SQL_SCRIPT)
    SET @SQL_SCRIPT  = 'CREATE TABLE ' + @TestDWName + '.dbo.[DimDate](
        [DateKey] [int] NOT NULL,
        [FullDateAlternateKey] [date] NOT NULL,
        [DayNumberOfWeek] [tinyint] NOT NULL,
        [EnglishDayNameOfWeek] [NVARCHAR](10) NOT NULL,
        [SpanishDayNameOfWeek] [NVARCHAR](10) NOT NULL,
        [FrenchDayNameOfWeek]  [NVARCHAR](10) NOT NULL,
        [DayNumberOfMonth] [tinyint] NOT NULL,
        [DayNumberOfYear]  [smallint] NOT NULL,
        [WeekNumberOfYear] [tinyint] NOT NULL,
        [EnglishMonthName] [NVARCHAR](10) NOT NULL,
        [SpanishMonthName] [NVARCHAR](10) NOT NULL,
        [FrenchMonthName]  [NVARCHAR](10) NOT NULL,
        [MonthNumberOfYear] [tinyint] NOT NULL,
        [CalendarQuarter]  [tinyint] NOT NULL,
        [CalendarYear] [smallint] NOT NULL,
        [CalendarSemester] [tinyint] NOT NULL,
        [FiscalQuarter] [tinyint] NOT NULL,
        [FiscalYear] [smallint] NOT NULL,
        [FiscalSemester] [tinyint] NOT NULL,
        CONSTRAINT [PK_DimDate_DateKey] PRIMARY KEY CLUSTERED
        (
        [DateKey] ASC
        )
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
        CONSTRAINT [AK_DimDate_FullDateAlternateKey] UNIQUE NONCLUSTERED
        (
        [FullDateAlternateKey] ASC
        )
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        ) ON [PRIMARY]'
    -- SELECT @SQL_SCRIPT
    EXEC (@SQL_SCRIPT)
END
ELSE IF @SQLResult = 0 /*doesn't exist*/
BEGIN
    SET @SQL_SCRIPT  = 'CREATE TABLE ' + @TestDWName + '.dbo.[DimDate](
    [DateKey] [int] NOT NULL,
    [FullDateAlternateKey] [date] NOT NULL,
    [DayNumberOfWeek] [tinyint] NOT NULL,
    [EnglishDayNameOfWeek] [NVARCHAR](10) NOT NULL,
    [SpanishDayNameOfWeek] [NVARCHAR](10) NOT NULL,
    [FrenchDayNameOfWeek]  [NVARCHAR](10) NOT NULL,
    [DayNumberOfMonth] [tinyint] NOT NULL,
    [DayNumberOfYear]  [smallint] NOT NULL,
    [WeekNumberOfYear] [tinyint] NOT NULL,
    [EnglishMonthName] [NVARCHAR](10) NOT NULL,
    [SpanishMonthName] [NVARCHAR](10) NOT NULL,
    [FrenchMonthName]  [NVARCHAR](10) NOT NULL,
    [MonthNumberOfYear] [tinyint] NOT NULL,
    [CalendarQuarter]  [tinyint] NOT NULL,
    [CalendarYear] [smallint] NOT NULL,
    [CalendarSemester] [tinyint] NOT NULL,
    [FiscalQuarter] [tinyint] NOT NULL,
    [FiscalYear] [smallint] NOT NULL,
    [FiscalSemester] [tinyint] NOT NULL,
    CONSTRAINT [PK_DimDate_DateKey] PRIMARY KEY CLUSTERED
    (
    [DateKey] ASC
    )
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
    CONSTRAINT [AK_DimDate_FullDateAlternateKey] UNIQUE NONCLUSTERED
    (
    [FullDateAlternateKey] ASC
    )
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]'
    -- SELECT @SQL_SCRIPT
    EXEC (@SQL_SCRIPT)
END

-- Create function DateToDateId for later use
SET @SQL_SCRIPT  = 'SELECT @SQLResult = 1 FROM ' + @TestDWName + '.[sys].[all_objects] WHERE [name] = ''DateToDateId'''
SET @ParamDefinition = '@SQLResult AS tinyint Output'
SET @SQLResult = 0
EXEC sp_executesql @SQL_SCRIPT, @ParamDefinition, @SQLResult Output
-- SELECT @SQL_SCRIPT;

IF @SQLResult = 1 /*exists*/
BEGIN
    SET @SQL_SCRIPT  = 'USE ' + @TestDWName + '; DROP FUNCTION dbo.[DateToDateId]'
    EXEC (@SQL_SCRIPT)
END

-- Must use nested dynamic SQL here because SQL Server has limit for create function to be the only SQL statement in the script
SET @SQL_SCRIPT =  N'CREATE FUNCTION [dbo].[DateToDateId](@Date DATETIME)
    RETURNS INT
    AS
    BEGIN
    DECLARE @DateId  AS INT
    DECLARE @TodayId AS INT

    SET @TodayId = YEAR(GETDATE()) * 10000
    + MONTH(GETDATE()) * 100
    + DAY(GETDATE())

    -- If the date is missing, or a placeholder for a missing date, set to the Id for missing dates
    -- Else convert the date to an integer
    IF @Date IS NULL OR @Date = ''''1900-01-01'''' OR @Date = -1
    SET @DateId = -1
    ELSE
    BEGIN
    SET @DateId = YEAR(@Date) * 10000
    + MONTH(@Date) * 100
    + DAY(@Date)
    END

    -- If there is any data prior to 2000 it was incorrectly entered, mark it as missing
    IF @DateId BETWEEN 0 AND 19991231
    SET @DateId = -1

    -- Commented out for this project as future dates are OK
    -- If the date is in the future, do not allow it, change to missing
    -- IF @DateId > @TodayId
    --   SET @DateId = -1

    RETURN @DateId
    END'
SET @SQL_SCRIPT2 = 'USE ' + @TestDWName + '; EXEC sp_executesql N''' + @SQL_SCRIPT + '''';
-- SELECT @SQL_SCRIPT2
EXEC(@SQL_SCRIPT2);

-- Later we will be writing an INSERT INTO... SELECT FROM to insert the new record. I want to
-- join the day and month name memory variable tables, but need to have something to join to.
-- Since everything is calculated, we'll just create this little bogus table to have something
-- to select from.if exists (select * from sys.types where name = 'TestTableType')

-- CREATE table #BogusTable
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#BogusTable'))
BEGIN
    DROP TABLE #BogusTable -- drop the temp table
END

CREATE TABLE #BogusTable(PK TINYINT);
INSERT INTO #BogusTable SELECT 1

-- CREATE table #DayNameTable
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#DayNameTable'))
BEGIN
    DROP TABLE #DayNameTable -- drop the temp table
END

CREATE TABLE #DayNameTable
(   [DayNumberOFWeek]  TINYINT
, [EnglishDayNameOfWeek] NVARCHAR(10)
, [SpanishDayNameOfWeek] NVARCHAR(10)
, [FrenchDayNameOfWeek]  NVARCHAR(10)
);
INSERT INTO #DayNameTable([DayNumberOFWeek],[EnglishDayNameOfWeek],[SpanishDayNameOfWeek],[FrenchDayNameOfWeek]) values
    (1,'Sunday','Domingo','Dimanche'),
    (2,'Monday','Lunes','Lundi'),
    (3,'Tuesday','Martes','Mardi'),
    (4,'Wednesday','Miércoles','Mercredi'),
    (5,'Thursday','Jueves','Jeudi'),
    (6,'Friday','Viernes','Vendredi'),
    (7,'Saturday','Sábado','Samedi');

-- CREATE table #MonthNameTable
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#MonthNameTable'))
BEGIN
    DROP TABLE #MonthNameTable -- drop the temp table
END
CREATE TABLE #MonthNameTable
    (   [MonthNumberOfYear] TINYINT
    , [EnglishMonthName]  NVARCHAR(10)
    , [SpanishMonthName]  NVARCHAR(10)
    , [FrenchMonthName]   NVARCHAR(10)
    );
INSERT INTO #MonthNameTable([MonthNumberOfYear],[EnglishMonthName],[SpanishMonthName],[FrenchMonthName]) values
    (1,'January','Enero','Janvier'),
    (2,'February','Febrero','Février'),
    (3,'March','Marzo','Mars'),
    (4,'April','Abril','Avril'),
    (5,'May','Mayo','Mai'),
    (6,'June','Junio','Juin'),
    (7,'July','Julio','Juillet'),
    (8,'August','Agosto','Août'),
    (9,'September','Septiembre','Septembre'),
    (10,'October','Octubre','Octobre'),
    (11,'November','Noviembre','Novembre'),
    (12,'December','Diciembre','Décembre');

-- Define the sql script to add DimDate
SET @SQL_SCRIPT  = 'USE ' + @TestDWName + ';
    SET NOCOUNT ON
    -- CurrentDate will be incremented each time through the loop below.
    DECLARE @CurrentDate AS DATE;
    SET @CurrentDate = @FromDate;

    -- FiscalDate will be set six months into the future from the CurrentDate
    DECLARE @FiscalDate  AS DATE;

    -- Now we simply loop over every date between the From and Thru, inserting the
    -- calculated into DimDate.
    WHILE @CurrentDate <= @ThruDate
    BEGIN
    SET @FiscalDate = DATEADD(m, 6, @CurrentDate)
    INSERT INTO dbo.DimDate
    SELECT [dbo].[DateToDateId](@CurrentDate)
    , @CurrentDate
    , DATEPART(dw, @CurrentDate) AS DayNumberOFWeek
    , d.EnglishDayNameOfWeek
    , d.SpanishDayNameOfWeek
    , d.FrenchDayNameOfWeek
    , DAY(@CurrentDate) AS DayNumberOfMonth
    , DATEPART(dy, @CurrentDate) AS DayNumberOfYear
    , DATEPART(wk, @CurrentDate) AS WeekNumberOfYear
    , m.EnglishMonthName
    , m.SpanishMonthName
    , m.FrenchMonthName
    , MONTH(@CurrentDate) AS MonthNumberOfYear
    , DATEPART(q, @CurrentDate) AS CalendarQuarter
    , YEAR(@CurrentDate) AS CalendarYear
    , IIF(MONTH(@CurrentDate) < 7, 1, 2) AS CalendarSemester
    , DATEPART(q, @FiscalDate) AS FiscalQuarter
    , YEAR(@FiscalDate) AS FiscalYear
    , IIF(MONTH(@FiscalDate) < 7, 1, 2) AS FiscalSemester
    FROM #BogusTable
    JOIN #DayNameTable d ON DATEPART(dw, @CurrentDate) = d.[DayNumberOFWeek]
    JOIN #MonthNameTable m ON MONTH(@CurrentDate) = m.MonthNumberOfYear;
    SET @CurrentDate = DATEADD(d, 1, @CurrentDate)
    END'

SET @ParamDefinition = '@FromDate AS NVARCHAR(10), @ThruDate AS NVARCHAR(10)';
--SELECT @SQL_SCRIPT;
EXEC sp_executesql @SQL_SCRIPT, @ParamDefinition, @FromDate, @ThruDate

/*drop all temp tables*/
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#BogusTable'))
BEGIN
    DROP TABLE #BogusTable -- drop the temp table
END
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#DayNameTable'))
BEGIN
    DROP TABLE #DayNameTable -- drop the temp table
END
IF EXISTS(SELECT 1 FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#MonthNameTable'))
BEGIN
    DROP TABLE #MonthNameTable -- drop the temp table
END

/*drop the function */
SET @SQL_SCRIPT  = 'SELECT @SQLResult = 1 FROM ' + @TestDWName + '.[sys].[all_objects] WHERE [name] = ''DateToDateId'''
SET @ParamDefinition = '@SQLResult As tinyint Output'
SET @SQLResult = 0
EXEC sp_executesql @SQL_SCRIPT, @ParamDefinition, @SQLResult Output
-- SELECT @SQL_SCRIPT;

IF @SQLResult = 1/*exists*/
BEGIN
    SET @SQL_SCRIPT  = 'USE ' + @TestDWName + '; DROP FUNCTION dbo.[DateToDateId]'
    EXEC (@SQL_SCRIPT)
END
Source: http://arcanecode.com/2013/12/08/updating-adventureworksdw2012-for-2014/

How to handle SSIS Package Protection Level with DontSaveSensitive option

Protection Level is a SSIS Package property that is used to specify how sensitive information was stored.  You can check SSIS Package code, which is XML file, and for any attributes with Senstive="1", they would be handled by SSIS Package Protection Level configuration. For example, password would be one sensitive information.

<DTS:Password DTS:Name="Password" Sensitive="1">

The ProtectionLevel property can be selected from the following list of available options after you right click on the SSIS package and show the package properties:
  • DontSaveSensitive
  • EncryptSensitiveWithUserKey
  • EncryptSensitiveWithPassword
  • EncryptAllWithPassword
  • EncryptAllWithUserKey
  • ServerStorage

DontSaveSensitive 
means when you save your package, those sensitive information will not be saved to the package xml file. Before you set this option, the password area of OLE DB Connection Manager will be displayed with black doted hidden string. 


After you set the package with this option, the password area of OLE DB Connection Manager will be displayed with empty.


Note the default option for SSIS Protection Level would be EncryptSensitiveWIthUserKey. If you decided to change to DontSaveSensitive, you need to save your sensitive information somewhere else, otherwise, when you execute your package, following error mistake would appear:
Error: 0xC0202009 at Package, Connection manager "runeet2k8.sa": An OLE DB error has occurred. Error code: 0x80040E4D.
An OLE DB record is available.  Source: "Microsoft SQL Native Client"  Hresult: 0x80040E4D  Description: "Login failed for user 'sa'.".

This is because the password has been cleared out from the package, and thus the connection manager suffered from login failure.

You can  save your sensitive information to SSIS package configuration file.
First, you open Package Configuration in BIDS.

A package Configuration Organizer pop up window will appear.

Click on the Edit button, and the Package Configuration Wizard popup window will appear. You can specify the configuration file name, and type.


Click on the Next, then choose which properties to export. Here we choose password. Click Next button and choose Finish.


After you finished the SSIS package configuration, you need manually add your password into the configuration file.

<DTSConfiguration>
    <DTSConfigurationHeading>
        <DTSConfigurationFileInfo GeneratedBy="FAREAST\runeetv" GeneratedFromPackageName="Package" GeneratedFromPackageID="{77FB98FB-E1AF-48D9-8A43-9FD6B1790837}" GeneratedDate="22-12-2009 16:12:59"/>
    </DTSConfigurationHeading>
    <Configuration ConfiguredType="Property" Path="\Package.Connections[runeet2k8.sa].Properties[Password]" ValueType="String">
        <ConfiguredValue>Your Password</ConfiguredValue>
    </Configuration>
</DTSConfiguration>
Source: https://www.mssqltips.com/sqlservertip/2091/securing-your-ssis-packages-using-package-protection-level/
http://blogs.msdn.com/b/runeetv/archive/2009/12/22/ssis-package-using-sql-authentication-and-dontsavesensitive-as-protectionlevel.aspx