<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'SQL Server', 'SQL Server 2008', and 'variables'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=SQL+Server,SQL+Server+2008,variables&amp;orTags=0</link><description>Search results matching tags 'SQL Server', 'SQL Server 2008', and 'variables'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Parent-Child Build Scripts with SQLCMD</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/01/10/parent-child-build-scripts-with-sqlcmd.aspx</link><pubDate>Sun, 10 Jan 2010 18:33:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:20821</guid><dc:creator>Mike C</dc:creator><description>&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;On the &lt;A href="http://groups.google.com/group/microsoft.public.sqlserver.programming/browse_thread/thread/7837d5428e6c83fd?hl=en#"&gt;SQL Server public programming newsgroup&lt;/A&gt; someone recently posted a question about an SSMS error (&lt;A href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=269566#details"&gt;"Cannot parse script. 'System.OutOfMemoryException' thrown."&lt;/A&gt;) I hadn’t encountered this error myself, but the workaround is to break up very large scripts (50+ MB) into smaller scripts. Adam Machanic posted a T-SQL Tuesday challenge to post &lt;A href="http://sqlblog.com/blogs/adam_machanic/archive/2010/01/04/invitation-for-t-sql-tuesday-002-a-puzzling-situation.aspx"&gt;a solution to a puzzling situation&lt;/A&gt;, so this actually gives me a good opportunity to share how I structure my own build scripts -- which avoids this issue entirely.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;When I create database build scripts, I use the&amp;nbsp;&lt;A href="http://msdn.microsoft.com/en-us/library/ms162773.aspx"&gt;SQLCMD&lt;/A&gt; utility to run them from the command line instead of using SSMS or another tool. SQLCMD has its own &lt;A href="http://msdn.microsoft.com/en-us/library/ms162773.aspx#sectionToggle3"&gt;commands&lt;/A&gt;, which it parses separately from SQL/T-SQL statements. These commands are not understood by SQL Server or other scripting tools like SSMS (&lt;I style="mso-bidi-font-style:normal;"&gt;exception: you can run SSMS in &lt;A href="http://msdn.microsoft.com/en-us/library/ms174187.aspx"&gt;SQLCMD mode&lt;/A&gt;, but that’s another story&lt;/I&gt;). These special SQLCMD commands all start with a ":" at the front of the line.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;The SQLCMD command that makes parent-child structured build-scripts possible is the ":r" or "run" command, which tells SQLCMD to run another script file from within the current script file. In the figure below I’ve set up a local directory structure with database object creation scripts in subdirectories:&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;IMG style="WIDTH:367px;HEIGHT:544px;" src="http://e60ybw.bay.livefilestore.com/y1pbBwOsoJdF21J9eW0lf7zCk782rocpyFX5YFOkwiggop15Lzj9HOBHrhOEoj0jRq7wdUr8BaYFFcpRou_irLDIAXzS_bY7al3/sqlcmd-folders.png" width=367 height=544&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;SPAN style="mso-no-proof:yes;"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;The &lt;EM&gt;\Scripts&lt;/EM&gt; directory contains a &lt;EM&gt;Create.All.Sql&lt;/EM&gt; script. This script uses the SQLCMD &lt;EM&gt;run&lt;/EM&gt; command to execute the &lt;EM&gt;Database\Create.Database.Sql&lt;/EM&gt; script, the &lt;EM&gt;Create.All.Schemas.Sql&lt;/EM&gt; script, and so on.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;The &lt;EM&gt;Create.All.Schemas.Sql&lt;/EM&gt; script calls the &lt;EM&gt;Person.Schema.Sql&lt;/EM&gt; and &lt;EM&gt;Sales.Schema.Sql&lt;/EM&gt; scripts in turn. The other &lt;EM&gt;Create.All.*&lt;/EM&gt; scripts each call the object creation scripts in their subdirectories as well. Here’s what my Create.All.Sql script looks like:&lt;/FONT&gt;&lt;/P&gt;&lt;PRE&gt;/*&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Create All Items&lt;BR&gt;*/&lt;BR&gt;&lt;BR&gt;
:r Database\Create.Database.sql&lt;BR&gt;:r Schemas\Create.All.Schemas.sql&lt;BR&gt;:r Types\Create.All.Types.sql&lt;BR&gt;:r Tables\Create.All.Tables.sql&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;Each &lt;EM&gt;:r&lt;/EM&gt; command kicks off the next level of child packages in turn.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;SQLCMD has another great feature known as scripting variables that you can use to create dynamic scripts. Essentially you define a scripting variable on the command line with SQLCMD's &lt;EM&gt;-v&lt;/EM&gt; command line option. Now the way scripting variables work, they are replaced wholesale in your scripts with their replacement value. So if you define a scripting variable named &lt;EM&gt;environment&lt;/EM&gt; you can replace it with a value like "Dev", "QA" or "Prod" anywhere it occurs in your script. This is great for making dynamic scripts that need to be built across multiple environments.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;In the example I've used a scripting variable named &lt;EM&gt;database&lt;/EM&gt;. You can set the value of the &lt;EM&gt;database&lt;/EM&gt; variable from the command line with the &lt;EM&gt;-v&lt;/EM&gt; option. In the example below I set the &lt;EM&gt;database&lt;/EM&gt; variable to the value "Test".&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;&lt;IMG style="WIDTH:843px;HEIGHT:187px;" title="SQLCMD Sample Command Line" alt="SQLCMD Sample Command Line" src="http://e60ybw.bay.livefilestore.com/y1py7Y3IXJHMFCeZDgZtZNWmVfQwxljC67X_AsNqD8JsJ1OM2OCxuApxSfz5V1Ze44963nb3_tZV4GUah4-4Dj0disbCrc5c7FD/Set-Scripting-Variable.png" width=843 height=187&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;SPAN style="mso-no-proof:yes;"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;The nice thing about the SQLCMD scripting variables is that once you declare them you can access them from the parent script you run (in this case &lt;EM&gt;Create.All.Sql&lt;/EM&gt;) or from any child scripts that are run (like &lt;EM&gt;Create.Database.Sql&lt;/EM&gt;, &lt;EM&gt;Create.All.Schemas.Sql&lt;/EM&gt;, &lt;EM&gt;Person.Schema.Sql&lt;/EM&gt; and &lt;EM&gt;Sales.Schema.Sql&lt;/EM&gt;). Here’s the &lt;EM&gt;Create.Database.Sql&lt;/EM&gt; script from the example:&lt;/FONT&gt;&lt;/P&gt;&lt;PRE&gt;/*&lt;BR&gt;&lt;BR&gt;&amp;nbsp;Create database&lt;BR&gt;&lt;BR&gt;*/&lt;BR&gt;&lt;BR&gt;USE master;&lt;BR&gt;GO&lt;BR&gt;&lt;BR&gt;
CREATE DATABASE &lt;STRONG&gt;&lt;U&gt;$(database)&lt;/U&gt;&lt;/STRONG&gt;;&lt;BR&gt;GO&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;The scripting variable is accessed in the script with &lt;EM&gt;$(database)&lt;/EM&gt;. The scripting variable is replaced with its value by SQLCMD, so in the example SQL Server sees this:&lt;/FONT&gt;&lt;/P&gt;&lt;PRE&gt;/*&lt;BR&gt;&lt;BR&gt;&amp;nbsp;Create database&lt;BR&gt;&lt;BR&gt;*/&lt;BR&gt;&lt;BR&gt;USE master;&lt;BR&gt;GO&lt;BR&gt;&lt;BR&gt;
CREATE DATABASE &lt;STRONG&gt;&lt;U&gt;Test&lt;/U&gt;&lt;/STRONG&gt;;&lt;BR&gt;GO&lt;FONT size=3 face=Calibri&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;One thing to keep in mind when you use this scripting pattern is that every script should end with the batch terminator (default is "GO").&amp;nbsp; If not you could end up with one script running into another and get some strange, not-very-helpful&amp;nbsp;error messages.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;Another thing you need to know is that scripting variables are replaced &lt;EM&gt;wholesale&lt;/EM&gt; with their replacement text. This makes&amp;nbsp;them very flexible, since you can replace text anywhere in the script with anything you want. It can also be dangerous if your script is run by someone with malicious intent. A malicious user can replace a scripting variable with T-SQL statements that could damage your data or database structure; so keep your scripting variable-enabled scripts out of the hands of potentially malicious users.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;I've attached a sample ZIP file with the directory structure shown in the example above. The scripts build out a few database objects from the AdventureWorks sample database.&lt;/FONT&gt;&lt;/P&gt;</description></item></channel></rss>