<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Huddled Masses &#187; Databases</title>
	<atom:link href="http://huddledmasses.org/tag/databases/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Fri, 27 Apr 2012 05:42:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<cloud domain='huddledmasses.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Adventures getting MSBuild, TFS and SQL Server Data Tools to work together</title>
		<link>http://huddledmasses.org/adventures-getting-msbuild-tfs-and-sql-server-data-tools-to-work-together/</link>
		<comments>http://huddledmasses.org/adventures-getting-msbuild-tfs-and-sql-server-data-tools-to-work-together/#comments</comments>
		<pubDate>Fri, 27 Apr 2012 05:42:40 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Deploy]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[Publish]]></category>
		<category><![CDATA[SSDT]]></category>
		<category><![CDATA[TFSBuild]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1830</guid>
		<description><![CDATA[We recently found that our database project at work goes from a 40-minute build and compile to about 20 minutes when we upgrade from the VS2010 (SQL 2008) database projects (with the old .dbproj files) to the new SQL Server Data Tools (SSDT) projects with the .sqlproj files, even though we&#8217;re still deploying to SQL [...]]]></description>
			<content:encoded><![CDATA[	<p>We recently found that our database project at work goes from a 40-minute build and compile to about 20 minutes when we upgrade from the VS2010 (<span class="caps">SQL</span> 2008) database projects (with the old .dbproj files) to the new <span class="caps">SQL</span> Server Data Tools (<span class="caps">SSDT</span>) projects with the .sqlproj files, even though we&#8217;re still deploying to <span class="caps">SQL</span> Server 2008 R2. So our goal immediately became:</p>

	<h3>Get the <span class="caps">SSDT</span> projects to compile with parameters from MSBuild</h3>

	<p>The problem is that with the new .sqlproj and the <code>SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets</code> there&#8217;s no built-in way to pass the database name or even a connection string when building the project via MSBuild &#8212; which is a critical part of our continuous integration builds.  The project I&#8217;m working on these days has 7 or 8 teams working in up to twice that many branches, and all those branches need CI builds, every one of which deploys the database project and validates it.  Since the branches change at least once a week, it&#8217;s way too much work to run around modifying publish.xml files to change database names every time we create a new branch (which we need to do to avoid the builds deploying over the top of each other).  </p>

	<p>With the old .dbproj format, there was a SQLDeploy task called in the <code>TeamData\Microsoft.Data.Schema.SqlTasks.targets</code> build target file which included a whole bunch of variables that could be overridden on the command line, so we could pass <code>TargetDatabase</code> and <code>TargetConnectionString</code> as MSBuild arguments, and then, to be able to compile the whole solution and still call the <strong>Deploy</strong> target, we added this to the project file:</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PropertyGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DBDeployOnBuild</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(DBDeployOnBuild)' == ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>False<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DBDeployOnBuild<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PropertyGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Target</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;AfterBuild&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;CallTarget</span> <span style="color: #000066;">Targets</span>=<span style="color: #ff0000;">&quot;Deploy&quot;</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(DBDeployOnBuild)'=='True'&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>

	<p>In our workflow, we redefine MSBuildArguments in the workflow, and now we can msbuild the whole solution and the database will be deployed:</p>

	<div class="vb code vb" style="font-family:monospace;"><br />
MSBuildArguments &amp; &quot; /p:DBDeployOnBuild=<span style="color: #000080;">True</span>;TargetDatabase=&quot;&quot;&quot; &amp; BuildDetail.BuildDefinition.Name &amp; &quot;&quot;&quot;;TargetConnectionString=...&quot;<br />
&nbsp;</div>

	<h3>But that doesn&#8217;t work with the new <span class="caps">SSDT</span> project type.</h3>

	<p>First of all, they don&#8217;t deploy with all their dependencies, instead, they have to be published.  It&#8217;s basically the same thing, with a different name.  But the SqlPublish task <strong>requires all the parameters to be in an xml file,</strong> and there&#8217;s no build properties we can override, because the properties are hiding in that publish.xml file that doesn&#8217;t get tokenized</p>

	<p>I&#8217;ve spent the last couple of days figuring out a work around, so I figured I should blog it up here and help the next guy.  The process is not simple.  The bottom line is that I haven&#8217;t found a way to get the SQLPublish task to take it&#8217;s values from anywhere except a publish xml file, so the solution I came up with was to rewrite the publish file using the <span class="caps">XDT</span> transform tasks defined for Web.config transforms.</p>

	<h3>Web.Config Transforms, on random <span class="caps">XML</span> files</h3>

	<p>The cool thing is, there&#8217;s actually a <code>ParameterizeTransformXml</code> task which allows you to define your transform as a string in the build file. </p>

	<div class="xml code xml" style="font-family:monospace;"><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;UsingTask</span> <span style="color: #000066;">TaskName</span>=<span style="color: #ff0000;">&quot;ParameterizeTransformXml&quot;</span> <span style="color: #000066;">AssemblyFile</span>=<span style="color: #ff0000;">&quot;$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp;</div>

	<p>In web projects, that task is used to replace connection strings (to hide them in web packages), but we can use it to replace the database name in our publish.xml.  In fact, I can actually add the same properties to the build that we used to have with the old project format (and which we&#8217;ll define on the command-line, <em>exactly</em> the way we did before). We put some default properties for TargetDatabaseName and TargetConnectionString in our Debug.publish.xml and our CI.publish.xml and then we just replace them during the build.  </p>

	<p>It&#8217;s a lot more complicated than what we had to do previously, partly because we need to define the <code>SqlPublishProfilePath</code> for the Publish task, but we have to use <code>CallTarget</code> to call the Publish target (not Deploy this time), which doesn&#8217;t support passing properties, nor does the target you call inherit properties that are defined in your scope.  This means we need to define the <code>SqlPublishProfilePath</code> property in the <code>BeforePublish</code> target which the publish target depends on (the &#8220;dependson&#8221; relationship inherits defined properties).</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Target</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;AfterBuild&quot;</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(DBDeployOnBuild)'=='True'&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;CallTarget</span> <span style="color: #000066;">Targets</span>=<span style="color: #ff0000;">&quot;Publish&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Target</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;BeforePublish&quot;</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;('$(TargetDatabase)' != '' Or '$(TargetConnectionString)' != '') And Exists($(TransformOutputFile))&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PropertyGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;SqlPublishProfilePath<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(TransformOutputFile)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/SqlPublishProfilePath<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PropertyGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>

	<p>But the real work is actually setting up the <strong>TransformPublishXml</strong> property with the right <span class="caps">XML</span> to replace the nodes with the properties from the command-line arguments, and then actually calling the task.  Since we imported the task before, we just need a property group to define our variables with default values, and then a <code>BeforeBuild</code> target to actually call the ParameterizeTransformXml:</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PropertyGroup</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(TargetDatabase)' != '' Or '$(TargetConnectionString)' != ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DBDeployOnBuild</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(DBDeployOnBuild)' == ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>False<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DBDeployOnBuild<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TargetConnectionStringXml</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(TargetConnectionString)' != ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>TargetConnectionString xdt:Transform=&quot;Replace&quot;<span style="color: #ddbb00;">&amp;gt;</span>$(TargetConnectionString)<span style="color: #ddbb00;">&amp;lt;</span>/TargetConnectionString<span style="color: #ddbb00;">&amp;gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TargetConnectionStringXml<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TargetDatabaseXml</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(TargetDatabase)' != ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>TargetDatabaseName xdt:Transform=&quot;Replace&quot;<span style="color: #ddbb00;">&amp;gt;</span>$(TargetDatabase)<span style="color: #ddbb00;">&amp;lt;</span>/TargetDatabaseName<span style="color: #ddbb00;">&amp;gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TargetDatabaseXml<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformPublishXml<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><span style="color: #ddbb00;">&amp;lt;</span>?xml version=&quot;1.0&quot;?<span style="color: #ddbb00;">&amp;gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>Project xmlns:xdt=&quot;http://schemas.microsoft.com/XML-Document-Transform&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;<span style="color: #ddbb00;">&amp;gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>PropertyGroup<span style="color: #ddbb00;">&amp;gt;</span>$(TargetConnectionString)$(TargetDatabaseXml)<span style="color: #ddbb00;">&amp;lt;</span>/PropertyGroup<span style="color: #ddbb00;">&amp;gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>/Project<span style="color: #ddbb00;">&amp;gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformPublishXml<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformFile</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(SqlPublishProfilePath)' != ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>$(SqlPublishProfilePath)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformFile<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformFile</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(SqlPublishProfilePath)' == ''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>$(Configuration).publish.xml<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformFile<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformFile</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$([System.IO.Path]::IsPathRooted($(TransformFile)))' == 'False'&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>$(MSBuildProjectDirectory)$(TransformFile)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformFile<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">&lt;!-- In order to do a transform, we HAVE to change the SqlPublishProfilePath--&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;BuildDefinitionName</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(BuildDefinitionName)' ==''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>VSBuild<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/BuildDefinitionName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformOutputFile<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(MSBuildProjectDirectory)$(BuildDefinitionName)_$(Configuration).publish.xml<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformOutputFile<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformScope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)))<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformScope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformStackTraceEnabled</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;'$(TransformStackTraceEnabled)'==''&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>False<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformStackTraceEnabled<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PropertyGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;UsingTask</span> <span style="color: #000066;">TaskName</span>=<span style="color: #ff0000;">&quot;ParameterizeTransformXml&quot;</span> <span style="color: #000066;">AssemblyFile</span>=<span style="color: #ff0000;">&quot;$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Target</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;BeforeBuild&quot;</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;('$(TargetDatabase)' != '' Or '$(TargetConnectionString)' != '')&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Message</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;The Target Database: '$(TargetDatabase)' and Connection String: '$(TargetConnectionString)'&quot;</span> <span style="color: #000066;">Importance</span>=<span style="color: #ff0000;">&quot;high&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">&lt;!-- If TargetDatabase or TargetConnectionString is passed in</span><br />
<span style="color: #808080; font-style: italic;"> &nbsp; &nbsp; &nbsp; &nbsp; Then we use the tokenize transform to create a parameterized sql publish file--&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Error</span> <span style="color: #000066;">Condition</span>=<span style="color: #ff0000;">&quot;!Exists($(TransformFile))&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;The SqlPublish Profile '$(TransformFile)' does not exist, please specify a valid file using msbuild /p:SqlPublishProfilePath='Path'&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ParameterizeTransformXml</span> <span style="color: #000066;">Source</span>=<span style="color: #ff0000;">&quot;$(TransformFile)&quot;</span> <span style="color: #000066;">IsSourceAFile</span>=<span style="color: #ff0000;">&quot;True&quot;</span> <span style="color: #000066;">Transform</span>=<span style="color: #ff0000;">&quot;$(TransformPublishXml)&quot;</span> <span style="color: #000066;">IsTransformAFile</span>=<span style="color: #ff0000;">&quot;False&quot;</span> <span style="color: #000066;">Destination</span>=<span style="color: #ff0000;">&quot;$(TransformOutputFile)&quot;</span> <span style="color: #000066;">IsDestinationAFile</span>=<span style="color: #ff0000;">&quot;True&quot;</span> <span style="color: #000066;">Scope</span>=<span style="color: #ff0000;">&quot;$(TransformScope)&quot;</span> <span style="color: #000066;">StackTrace</span>=<span style="color: #ff0000;">&quot;$(TransformStackTraceEnabled)&quot;</span> <span style="color: #000066;">SourceRootPath</span>=<span style="color: #ff0000;">&quot;$(MSBuildProjectDirectory)&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ParameterizeTransformXml<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>

	<p>So all you have to do is put those three blocks of <span class="caps">XML</span> at the bottom of your .sqlproj file, and then call <code>msbuild</code> with <code>/p:TargetDatabase=DBName;TargetConnectionString=&#34;Data Source=DBServer;User ID=sa;Password=password&#34;;DBDeployOnbuild=True</code> to get the database project to build <em>and deploy</em> to the database you want.</p>

	<p>If you&#8217;ve got questions, post &#8216;em &#8212; I&#8217;m writing this at 1:30 in the morning so I&#8217;m not at my most lucid  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=':-)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/adventures-getting-msbuild-tfs-and-sql-server-data-tools-to-work-together/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rant: Sometimes I hate my job</title>
		<link>http://huddledmasses.org/rant-sometimes-i-hate-my-job/</link>
		<comments>http://huddledmasses.org/rant-sometimes-i-hate-my-job/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 18:08:52 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Rants]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=564</guid>
		<description><![CDATA[So I&#8217;ve been asked to add a feature to one of the apps that I nominally took over when my former manager left &#8230; they want a management pane where certain authorized super users (to be decided later) can add data to the main lookup tables, and must be able to do clean up by [...]]]></description>
			<content:encoded><![CDATA[	<p>So I&#8217;ve been asked to add a feature to one of the apps that I <em>nominally</em> took over when my former manager left &#8230; they want a management pane where certain authorized super users (to be decided later) can add data to the main lookup tables, and must be able to do clean up by deleting data which has been entered erroneously &#8230; including cleaning up any references to the now missing data.</p>

	<p>I&#8217;m currently trying to figure out what database tables I need to be concerned with, and I just have to vent, because this system is the worst mess I&#8217;ve ever seen.  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[disgust]' class='wp-smiley' /> </p>

	<ul>
		<li>There&#8217;s one database supporting five or more applications&#8230;</li>
		<li>There are 87 tables (with names like tblAQ_DcSs, tblAQ_SwNw, tblSFM, and tblSW_PWSOS, tblTestCaseTestLayout )</li>
		<li>There are <strong>three</strong> duplicate user tables: tblPeopleLookup, tblUser, and tblUser3 &#8212; tblUser2 is a view onto an external user database which is what is <strong>supposedly</strong> being used &#8230; and apparently, tblPeopleLookup is some sort of mapping from tblUser2 to tblUser3 &#8230; and tblUser1 is the original user table. I don&#8217;t know why these are all still here &#8212; I can only hope none of these others are still being used.</li>
		<li>There are 144 stored procedures (with names like sp_Fix, sp_Fix2, sp_Fix3, spLeftToTestMulti, spLeftToTestMulti2, spLeftToTestMulti3, sp_Whatever, and the awesome spTestCaseTestLayoutTestsUpdate, spTestCaseTestLayoutTestsSelect, etc.)</li>
	</ul>
	<ul>
		<li>There are <strong>no</strong> Foreign Keys.  Yeah. None.  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[crazy]' class='wp-smiley' /> </li>
	</ul>

	<p>Technically, there are lots of foreign keys &#8212; it&#8217;s just that none of them are declared as such, so there&#8217;s no referential integrity (did I mention that there&#8217;s an access database floating around out there with linked tables and a hard-coded login which the end-users pass around to each other so they can insert data into some of the tables <strong>by hand</strong> because the original developers didn&#8217;t get around to writing this management app that I&#8217;ve been asked to write now?)</p>

	<p>You can tell that some of the columns <em>should</em> be Foreign Keys, because obviously a column in a &#8220;tblReq_Tag&#8221; table named &#8220;Feature_ID&#8221; must be an external lookup of some sort &#8230; but there&#8217;s 86 other tables &#8230; and at least two of them have Primary Keys called &#8220;Feature_ID&#8221; ...</p>

	<p>So, I&#8217;m spending a lot of time searching the source code and the 144 stored procedures &#8230; An astonishing number of these stored procedures involve cursors and multiple nested case statements.  I just picked one at random which I thought sounded simple: <strong>spEnterGroupResults</strong> ... it&#8217;s about 150 lines of <span class="caps">SQL</span>, and it uses a single cursor variable &#8220;crsUnit&#8221; which it redefines three separate times onto three different queries which it iterates over. Each of these queries involves joins onto nested subqueries, and I count myself lucky because the tricky part is actually enclosed in a transaction, and at least <em>this one</em> isn&#8217;t doing all of that just to dynamically generate a further <span class="caps">SQL</span> query to execute.</p>

	<p>So yeah, I&#8217;m literally looking through source code to try to understand the database design.  The problem is that there are more than five different applications, each using slightly different technologies.</p>

	<ul>
		<li>One of them which has never been migrated from classic <span class="caps">ASP</span> ... with the business logic written entirely in Javascript, and the data handling performed entirely by sending <strong>huge</strong> <span class="caps">XML</span> files back and forth to a &#8220;do all&#8221; webservice.</li>
		<li>One of them was written in VB.<span class="caps">NET</span> in VS 2003, and has never been upgraded.</li>
	</ul>
	<ul>
		<li>The rest are in C# &#8212; with most in VS 2005, and at least one in VS 2008 and C# 3.0 &#8212; some are Asp.Net, some are rich client &#8230;</li>
	</ul>

	<p>The tables I&#8217;m most concerned with right now (for this app) have some <em>ahem</em> ... impressive design decisions of their own.  Of the 8 tables that I&#8217;m looking at directly (I think these are the only ones I need to <em>modify</em> as part of this app), five of them have multi-column primary keys that involve more than half the columns in the table, including columns which are, in fact, unconstrained foreign keys.  And there are so far 5 foreign key looking columns which I haven&#8217;t been able to find the primary key column for &#8230;  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[pullhair]' class='wp-smiley' /> </p>

	<p> <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  <strong>Edit</strong>: Oh yeah, and half of these tables have columns like <code>[Enabled] [char](1) NULL</code> &#8230;  That&#8217;s a <strong>boolean</strong> value folks, stored in the database as a <code>y</code> or a <code>n</code> &#8230; and it&#8217;s nullable even though a null (or any value other than <code>y</code> or <code>n</code>, really) will most likely blow up some code somewhere.  And no, there&#8217;s no script constraint or trigger to ensure that this doesn&#8217;t happen (I checked). For extra fun, the other half of the tables use &#8216;bit&#8217; columns for things like this  &#8212; because they were written after I started working with this team (on a different project) and happened across one of these char columns during our one and only code review ever and wondered aloud why we needed to pretend it was still 1992.  Why they just switched, without changing the others, I&#8217;ll never know&#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/rant-sometimes-i-hate-my-job/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

