Wednesday, October 31, 2012

SSDT: External Database References

If your database references other databases, you'll need a *.dacpac file for each external database referenced in your code. For example, if you reference AdventureWorksDW2008 from Adventureworks2008, you'll need to add that as a database reference.
 
To add a Database Reference to your project
  • Right-click the "References" folder in your project or choose the "Project" menu and select the option to "Add Database Reference"
clip_image001
  • Browse for your dacpac file
  • Choose the appropriate database location. (Same, Different DB / Same Server, or Different DB / Different Server)
  • If your database name doesn't change, clear out the "Database Variable" column. It isn't immediately obvious, but doing this will let you keep referencing your database in the same manner you do currently.
    • If this database name can vary, populate the Database Variable field. You'll need to replace this reference in your code with the variable from this column.
    • If you're referencing a database on a linked server, this would probably be better served with a static database name and a "Server Variable". Make sure that server variable is set appropriately when you publish the database.
    • This should be addressed with a future release of SSDT.
  • You may choose to suppress errors if there are unresolved references in the project. This is useful if your dacpac file could be out of date. You can still code against an object you know to exist, but isn't in the reference file yet.
  • If you use Linked Servers, you’ll probably want to use the Server Variable to ensure that you can release your code in different environments.
clip_image002
 
Some Best Practices and Lessons Learned
  • Make a shared folder to store your dacpac files in a common place. This should be easily accessible from all of your SQL Projects.
    • If you use C:\DatabaseProjects as your base for all SQL Server projects, create a folder in there to store your shared dacpac files.
  • Because all paths are relative to the project, you may need to copy the master/msdb dacpac files that ship with SSDT into your shared folder. You can find these files in your Visual Studio folder in a path similar to the following.
Drive:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\SQLDB\Extensions\SqlServer\VersionNumber\SqlSchemas
    • If you support multiple SQL Server editions, you may want to rename master/msdb files with their user-friendly version number. E.g., the master.dacpac file in your "90" folder could be renamed to master2005.dacpac
    • This should be addressed in a future release of SSDT and could already be fixed.

  • If you use variables, don’t forget to replace any TSQL with the variable in the form of [$(VariableName)].
    • Square braces may not be necessary, but in most cases, they’ll work as expected for DB or Server names.
  • If you need to reference a dacpac that is already in use, you’ll need to create a copy of it. This comes up more often if you’re referencing a replicated database for which you already have a production dacpac.
  • Choose good variable names for the Server variable name.
  • Don’t forget to set the variables in the Project and/or Publication properties!




Tuesday, October 30, 2012

SSDT: SQL Project Options

To set the properties for your SQL Project, right-click the Project and select Properties. You'll see a window containing several tabs to define your project.
 
Project Settings
Here you can set your normal target platform (SQL 2005, 2008, 2012, or Azure).
You can enable the T-SQL verification option, but this is mostly for Azure projects.
If you will generally output to a script, choose the "Create script" option. On the whole, just using the dacpac file will likely provide greater flexibility in the long run as it can be adapted to a different target. Generating a script will only be guaranteed to work against the target used to generate the script.
clip_image001
You can also set the dacpac file properties, which sadly do not do much when used against a database not using these as data-tier applications. There is some talk of enhancing the projects to use this version number and description somewhere within the database, but right now they are pretty much only there for you to populate if you wish.
clip_image002
 
You can also set the Database Settings for your project. These options are the normal ones you would set when setting options in SQL Server. You can choose to publish these to your targets so set these to your preferences. (More on that in a future post.)
clip_image003
clip_image004
clip_image005
I'm going to bypass the SQLCLR and SQLCLR Build tabs as I am not familiar with them and don’t currently use either in our system.
 
Build
The Build tab is the place to specify which warnings to ignore, the output path for your files when you build the project, and the name of the file. You may want to specify certain warnings to ignore, especially if you use cross-database projects or any references to system databases. Those can often result in warnings about missing objects, even though they'll work perfectly fine when you publish them.
  • Note that the warnings are set per configuration. If you use multiple configurations be sure to set the warnings in each one.
clip_image006
 
clip_image006[1]
 
SQLCMD Variables
SQLCMD variables can be used throughout the project as placeholders for values passed in at publication time. For example, you may choose to change the way your scripts run based on your Development, Customer Acceptance, or Production environments. Define these variables here and use them wherever applicable in the project by inserting them as $(DeployType). SSDT will substitute them with the proper value on publication.
clip_image007
 
Build Events
Build events can be set up to run certain commands before and after the project is built. You can also choose to run the Post-Build event commands only when the project builds successfully or on every build.
 
Debug
Start Action and Target Connection String should make sense for those who need to change them. One item to note is that the debug action defaults to a SQL Express type instance of your database that is released to (localhost)\DBName. This will run within SSDT so you can try out your T-SQL before committing the changes in the project.
** Note that if you use FILESTREAM, you will not be able to use these user instances. You will need to change your debug database to a SQL Server install.
In your Deployment Options, you have a screen that looks something like this:
clip_image008
"Block incremental deployment" is one to be aware of. If you run into any constraints, refactoring, data type changes, NULL to NOT NULL, or similar changes, you could have your debug action stop unexpectedly. It can be really useful to avoid dropping columns that could contain data, but if you are aware of the changes, this option could also get in the way of normal releases. According to the MS documentation, this will only block the change if there is data in the table.
"DROP Objects in target but not in project" can be useful to make sure that everyone is running with what's in the project and that they don't have leftover objects that could interfere with testing. However, it's also possible to lose a bunch of work if you publish a project with this option against your local instance containing the stored procedure you've worked on for the last 2 weeks.
"Advanced" contains a lot of different options about what to compare and how to generate the changes. Some of the more interesting options include:
  • Allow incompatible platform - this will let you push your changes to a version of SQL Server other than the one specified in the project properties. The changes will fail if you try to do something not allowed in the target, but useful in case you have your project set to the lowest version supported.
  • "Drop xyz not in source" - these options control what will be dropped from the target if it's not defined in the source. The default options are likely good for most users.
  • "Ignore xyz" - defines what should be ignored when comparing the project against the target. You may want to ignore details about the partition schemes, or what permissions are set in the target
  • "Include Transactional Scripts" will set up the release script as transactions when publishing the database. This is useful when you want to make sure that if one part of the publish action fails, the change script is rolled back.
  • "Verify Deployment" - stops the publish actions if the script could run into some problems.
 
Reference Paths
This section is used to modify and maintain the various Server & Database variables used with cross-database references. See the "External Database References" page for more detail.
 
Code Analysis
This option can be useful to check for common issues such as using reserved words, non-standard characters in object names, or using "select *" in your queries. You can also specify whether to show these as errors or warnings. Set appropriately for your environment.









































Monday, October 29, 2012

SSDT: Importing an Existing Database

To Import From an Existing Database
Import Database into your project by right-clicking the project name or selecting the Project Menu and selecting the Import -> Database option. Note that you can also import from SQL Scripts or an existing dacpac file. One of those may be necessary if you don't have direct access to your source server.
clip_image001
You'll then be asked to choose your project name, location, folder structure, and what to import. You can choose the defaults if you want. If you have an intricate permissions structure, you may want to import the permissions. If your logins, users, and permissions tend to vary by environment, you may want a different way to handle those. That will be covered in the "Permissions" section.
You'll have several options for folder structure. I'd choose the recommended structure unless you have a reason to choose something else. That will structure all of your objects under their appropriate schema, by object type. If you have a relatively simple database model, you may choose to structure your project by schema alone, object type alone, or just put everything in the root of the project. This only affects your project file structure, not your database structure.
Once you're satisfied with your settings, click the "Start" button to begin populating your project.
clip_image002
 
Importing From a Dacpac File
SSDT supports importing from a dacpac file. This can be useful if you're working on a project for a database to which you do not have direct access in order to import the schema directly. These files also can be used as external database references if you work in an environment where multiple databases interact.
In order to create a dacpac file, you have a couple of options.
You can generate a dacpac file from a SQL Server database using SSMS 2012. Right-click the database you wish to use. Select Tasks, then "Extract Data-tier Application…".
clip_image003
Set the file location and any other options you want to use.
clip_image004
Click next. Verify the settings. Click Next again. The system will now generate a dacpac file in the location you specified.
Note that choosing the "Export Data-tier Application" will create a bacpac file. This is used to backup all schema and data in a database so it can be published to an Azure database. You cannot use a bacpac file to import schema into your project.
 
Generating a dacpac using SQLPackage.exe
You can always use the SQLPackage command line to extract the DB Schema into a dacpac file. For a complete list of parameters, see http://msdn.microsoft.com/en-us/library/hh550080%28v=VS.103%29.aspx.
For a quick extraction from a trusted server, you can run something like the following:
Code Snippet
  1. Sqlpackage.exe /a:extract /ssn:localhost /sdn:Adventureworks2008 /tf:Adventureworks2008.dacpac
This command uses an "Action" to Extract the file, with the SourceServerName of localhost, a SourceDatabaseName of Adventureworks2008, and a TargetFile of Adventureworks2008.dacpac




















Saturday, October 27, 2012

SSDT: Creating a New SQL Project

Download the latest SSDT package if you do not have the product installed already:
http://msdn.microsoft.com/en-us/data/tools.aspx
 
To create a new SQL Project, you can either start by creating a new Project or create a new project from an existing database.
When creating a brand new project, be sure to choose the "SQL Server Database Project".
clip_image001
 
This is not the same as the Database -> SQL Server Project template. Using this will create a usable DB Project, but not the newer SQL Project.
clip_image002
 
Once you've created a new, empty project, you'll need to populate the project in order to be able to use it. You have a couple of options. You can import from an existing database, import from a Dacpac file, or just start creating your objects if this is a completely new project.
 
To Start a New Project from a Connected Database
Open your "SQL Server Object Explorer" window. Connect to the database server containing the database for which you want to create a project. Right-click that database and choose the "Create New Project…" option.
clip_image003
You'll then be asked to choose your project name, location, folder structure, and what to import. You can choose the defaults if you want. If you have an intricate permissions structure, you may want to import the permissions. If your logins, users, and permissions tend to vary by environment, you may want a different way to handle those. That will be covered in the "Permissions" section.
You'll have several options for folder structure. I'd choose the recommended structure unless you have a reason to choose something else. That will structure all of your objects under their appropriate schema, by object type. If you have a relatively simple database model, you may choose to structure your project by schema alone, object type alone, or just put everything in the root of the project. This only affects your project file structure, not your database structure.
Once you're satisfied with your settings, click the "Start" button to begin populating your project.
clip_image004

















Friday, October 26, 2012

SSDT: Why Use SQL Projects?

What Are SQL Projects and why use them?
SQL Server has always been lacking in a good solution to control versions of your database. We make changes directly to the database and if we're good, we remember to take backups. If we're really good, we save scripts so we can make those changes elsewhere. Too often, we resort to tools for schema differences or try to save up all of the scripts to replay them later. Both have some advantages. Schema differences guarantee that you can make two environments look the same. Scripts can be replayed in order to keep the systems in sync. However, a schema difference doesn't handle data changes well and can't handle making partial changes when not everything is ready to promote. Sets of scripts can also work well, but fail if you end up needing to push sub-sets of those scripts because certain functionality isn't going to be released yet.
Borrowing from Gert Drapers' excellent discussions on Database Development Challenges:
  • Databases are inherently stateful
    • ALTERs are generally run instead of DROP/CREATE
    • Dependencies can greatly complicate the changes and scripts
    • Data needs to be persisted
  • Databases are often not integrated well with the application development life cycle
  • DB Versions are frequently not persisted or managed well
  • SQL Scripts may not handle different SQL Server versions well
Sequential Change Scripts
  • Required to run in a set order
    • Script 1, Script 2, Script 3, …
    • Can't do Script 1, Script 4, Script 9
  • Validating the end state after script runs vs. an expected end state can be complex
  • Could easily miss a script in the sequence without knowing
  • Handling a release where scripts need to be "skipped" can cause cascading dependency problems
  • Can require extensive use of IF NOT EXISTS statements
  • Manual process
  • Point in time model
  • Used by systems such as DBDiff
Declarative Model
  • The model is the desired end state
    • Compare the current state of the target against the desired end state
    • Use the differences to generate an upgrade plan
    • Use the upgrade plan to generate a change script, correctly ordered to bring the target up to the desired end state
  • Generated / Programmatic process
  • Always current
  • Used by Red Gate, Microsoft, DB Ghost
Microsoft and Red Gate have both provided solutions to store versions of database schemas. While Red Gate offers a good product, it also requires some external tools to provide a complete solution for schema control. Until recently, Microsoft's solution wasn't accessible to everyone because it required a copy of Visual Studio to handle even the basics. This improved in Visual Studio 2010, but still required a separate purchase. With SQL Server 2012, Microsoft introduced SQL Server Data Tools and SQL projects.
With SQL projects, developers can store a version of their database objects in a source control system of their choice. Tables, stored procedures, views, and even permissions can be stored in such a way as to provide upgrades to databases and even build a new set of databases from scratch. This could even be used to build and release these databases continuously in an automated fashion to release new code.