<?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>sides of march &#187; SQL</title>
	<atom:link href="http://www.sidesofmarch.com/index.php/archive/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sidesofmarch.com</link>
	<description>Thoughts on life, liberty, and information technology</description>
	<lastBuildDate>Mon, 16 Jan 2012 02:43:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Executing native SQL using NHibernate named queries</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2009/02/11/executing-native-sql-using-nhibernate-named-queries/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2009/02/11/executing-native-sql-using-nhibernate-named-queries/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 14:16:33 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[named queries]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/?p=340</guid>
		<description><![CDATA[<p>I&#8217;ve been doing a lot of work with <a href="http://www.nhforge.org">NHibernate</a> lately, particularly with <a href="http://www.hibernate.org/hib_docs/nhibernate/html/querysql.html">named queries</a>. It took a while to get it just right, so I figured it would be helpful to others (and to myself in the future) to note some of the gotchas and how-to steps to get it just right.</p>
<p><strong>What is a named query?</strong></p>
<p>An NHibernate named query is essentially a native SQL statement that can be invoked by NHibernate and can return strongly-typed object data. It allows you to leverage native SQL code &#8212; parametrized statements or stored procedures &#8212; to perform complex data manipulation and retrieval.</p>
<p>In other words, let&#8217;s say you&#8217;re writing a baseball game, and you have three objects in your domain model: a <strong>Player</strong>, a <strong>Team</strong>, and a <strong>DrugTestResult</strong> model. You write a stored procedure, spSelectPlayersByLastDrugTestDate, which returns all players who haven&#8217;t had a drug test since a given date.</p>
<p>Now that you have a domain model and a SQL statement, how do you execute <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2009/02/11/executing-native-sql-using-nhibernate-named-queries/">Executing native SQL using NHibernate named queries</a></span>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing a lot of work with <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fwww.nhforge.org&sref=rss">NHibernate</a> lately, particularly with <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fwww.hibernate.org%2Fhib_docs%2Fnhibernate%2Fhtml%2Fquerysql.html&sref=rss">named queries</a>. It took a while to get it just right, so I figured it would be helpful to others (and to myself in the future) to note some of the gotchas and how-to steps to get it just right.</p>
<p><strong>What is a named query?</strong></p>
<p>An NHibernate named query is essentially a native SQL statement that can be invoked by NHibernate and can return strongly-typed object data. It allows you to leverage native SQL code &#8212; parametrized statements or stored procedures &#8212; to perform complex data manipulation and retrieval.</p>
<p>In other words, let&#8217;s say you&#8217;re writing a baseball game, and you have three objects in your domain model: a <strong>Player</strong>, a <strong>Team</strong>, and a <strong>DrugTestResult</strong> model. You write a stored procedure, <code>spSelectPlayersByLastDrugTestDate</code>, which returns all players who haven&#8217;t had a drug test since a given date.</p>
<p>Now that you have a domain model and a SQL statement, how do you execute it through NHibernate?</p>
<p><strong>Mapping your named queries</strong></p>
<p>NHibernate needs to know about your named queries in order to execute them. Much like you tell NHibernate about your domain model using <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fwww.hibernate.org%2F362.html%23A9&sref=rss">XML mapping files</a> (*.hbm.xml), you tell NHibernate about your named queries using those same files.</p>
<p>Since the named query mappings do not relate directly to your domain model mappings, you can create a separate mappings file just for your named queries. A sample mappings file for our <code>spSelectPlayersByLastDrugTestDate</code> could look like the following.</p>
<pre class="brush: xml; ">

&lt; ?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;hibernate -mapping xmlns=&quot;urn:nhibernate-mapping-2.2&quot;&gt;
&lt;sql -query name=&quot;FindPlayerByLastDrugTest&quot;&gt;
&lt;query -param name=&quot;LastDrugTestDate&quot; /&gt;
&lt;return class=&quot;Player&quot;&gt;
&lt;return -property column=&quot;PlayerID&quot; name=&quot;PlayerID&quot; /&gt;
&lt;return -property column=&quot;PlayerName&quot; name=&quot;Name&quot; /&gt;
&lt;return -property column=&quot;TeamID&quot; name=&quot;Team&quot; /&gt;
&lt;return -property column=&quot;LastDrugTestID&quot; name=&quot;LastDrugTestResult&quot; /&gt;
&lt;/return&gt;
exec spSelectPlayersByLastDrugTestDate @LastDrugTest=:LastDrugTestDate
&lt;/sql&gt;
&lt;/hibernate&gt;
</pre>
<p>The named query part of the mapping is in the <code>&lt;sql-query&gt;</code> section. I&#8217;ll describe its most important sections below.</p>
<ul>
<li>The <strong>sql-query</strong> tag defines the named query. The <strong>name</strong> attribute is the name that NHibernate (and, in turn, your code) will use to reference the query. In our example, we are stating that this named query is called <code>FindPlayerByLastDrugTest</code>.</li>
<li>The <strong>query-param</strong> tag defines a parameter in your query. The <strong>name</strong> attribute reflects the name by which you are referring to that parameter, <em>not the parameter name in the actual SQL statement</em>. The <strong>type</strong> is the data type of that parameter. In our example, we have one parameter, <code>LastDrugTestDate</code>, which is a <code>DateTime</code>.</li>
<li>The <strong>return</strong> tag defines the type which is returned by the named query. In our example, the return type is a  <strong>class</strong>, <code>Player</code>. Our SQL statement must therefore return fields which map to the Player object. Note that named queries do not have to return domain model objects; they can return ordinals, other types, or nothing at all. (As a result, the <code>return</code> tag is optional.)</li>
<li>The many <strong>return-property</strong> tags tells NHibernate how to map a column in the query results (the <strong>column</strong> attribute) to a property name in the return type. NHibernate gets rather crafty here. For normal properties (<code>PlayerID</code> and <code>Name</code> in our example) the mappings are simple column-name-to-property-name. Note, however, the <code>TeamID</code> mapping, where we map a <code>TeamID</code> in our result set (which could be an integer, the primary key for a <code>Team</code> domain object) to a property named <code>Team</code>. In our domain model, the <code>Player.Team</code> property is not an integer, it is a <code>Team</code>. NHibernate, because it knows how a <code>Player</code> relates to a <code>Team</code>, will auto-map the player to the team. This nuance is important in getting your named queries to work with your domain model: you map foreign key values in your result set to objects in your data model. (A similar thing happens for the <code>LastDrugTestResult</code> property.)</li>
<li>Finally, after we close our return tag, we provide our <strong>actual SQL statement</strong>. This is a standard parametrized SQL statement with a twist. To <strong>inject your query-param values</strong> into the SQL statement, you specify :<em>Name</em> &#8212; that is, a colon followed by the <code>name</code> specified for the <code>query-param</code>.</li>
</ul>
<p>Got all that? Good. We&#8217;re almost done!</p>
<p><strong>Running your named queries</strong></p>
<p>Finally, the easy part &#8212; running the named query! Named queries are run against the NHibernate ISession. Various methods are available to set parameters using a fluent interface.</p>
<p>Running our <code>FindPlayerByLastDrugTest</code> query could look like this:</p>
<pre class="brush: c-sharp; ">

// get your NHibernate session however you normally would
//ISession session = ...

// create an IQuery based on your named query, specifying parameters
IQuery namedQuery = session.GetNamedQuery(&quot;FindPlayerByLastDrugTest&quot;)
.SetDateTime(new DateTime(2003, 1, 1));

// execute the query
IList list = query.List();

// if you were running a query that returned a single, scalar value, you could say...
var result = query.UniqueResult();
</pre>
<p>Note that there are generic versions of <code>List()</code> and <code>UniqueResult()</code>, but I had problems getting them to work. Not sure why (I didn&#8217;t dig that far), but the above queries will do the same (though they require some type-casting).</p>
<p>Named queries do a lot more. The following links may prove useful in your learning.</p>
<ul>
<li><a id="viewpost_ascx_TitleUrl" class="TitleLinkStyle" title="Title of this entry." href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fayende.com%2FBlog%2Farchive%2F2006%2F06%2F24%2FNHibernatesStoredProceduresNamedQueries.aspx&sref=rss">NHibernate&#8217;s &#8220;Stored Procedures&#8221; &#8211; Named Queries</a> (Ayende)</li>
<li><a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fwww.kenegozi.com%2Fblog%2F2008%2F05%2F09%2Fusing-nhibernates-named-queries-with-activerecord.aspx&sref=rss">Using nhibernate&#8217;s named queries with ActiveRecord</a> (Ken Egozi)</li>
<li><a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fnathan.whiteboard-it.com%2Farchive%2F2008%2F07%2F28%2Fnhibernate-bulk-updatesinsertsdeletes-with-named-queries.aspx&sref=rss">NHibernate Bulk Updates/Inserts/Deletes with Named Queries</a> (Nathan Scott)</li>
</ul>
<p>If you find other great resources, be sure to share!</p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=340&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2009/02/11/executing-native-sql-using-nhibernate-named-queries/' addthis:title='Executing native SQL using NHibernate named queries ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2009/02/11/executing-native-sql-using-nhibernate-named-queries/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Scripting the deletion of objects in a SQL database (second version)</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2008/09/11/scripting-the-deletion-of-objects-in-a-sql-database-second-version/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2008/09/11/scripting-the-deletion-of-objects-in-a-sql-database-second-version/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 16:46:39 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/?p=280</guid>
		<description><![CDATA[<p>A few weeks ago, I wrote a post about <a href="http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/">deleting all tables and constraints in a database</a>. It&#8217;s time to take that one step further!</p>
<p>The following SQL code will delete all stored procedures, user-defined functions (UDFs), views, table constraints, and tables (in that order) from a given SQL database. As with the original, you can specify an object name previx by changing the set @tblname = '' as needed.</p>
<p>This is helpful in two situations:</p>

When you want to delete all objects in a database without dropping/recreating it, in which case you&#8217;d specify '%' as the @tblname.
When you want to delete all objects in a database whose name starts with a certain sequence of characters. For example, if you want to delete all the <a href="http://static.asp.net/asp.net/images/security/04/images/aspnet_tutorial04_MembershipSetup_vb_figure10.png">ASP.Net membership objects</a> in a database, you can specify '%aspnet_%' as the @tblname, since its SQL objects start with aspnet_ or vw_aspnet_.

<p>Note that you should be <em>very careful</em> any time you use scripts like this, as data <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2008/09/11/scripting-the-deletion-of-objects-in-a-sql-database-second-version/">Scripting the deletion of objects in a SQL database (second version)</a></span>]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I wrote a post about <a href="http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/">deleting all tables and constraints in a database</a>. It&#8217;s time to take that one step further!</p>
<p>The following SQL code will delete all stored procedures, user-defined functions (UDFs), views, table constraints, and tables (in that order) from a given SQL database. As with the original, you can specify an object name previx by changing the <code>set @tblname = ''</code> as needed.</p>
<p>This is helpful in two situations:</p>
<ul>
<li>When you want to delete all objects in a database without dropping/recreating it, in which case you&#8217;d specify <code>'%'</code> as the <code>@tblname</code>.</li>
<li>When you want to delete all objects in a database whose name starts with a certain sequence of characters. For example, if you want to delete all the <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fstatic.asp.net%2Fasp.net%2Fimages%2Fsecurity%2F04%2Fimages%2Faspnet_tutorial04_MembershipSetup_vb_figure10.png&sref=rss">ASP.Net membership objects</a> in a database, you can specify <code>'%aspnet_%'</code> as the <code>@tblname</code>, since its SQL objects start with <code>aspnet_</code> or <code>vw_aspnet_</code>.</li>
</ul>
<p>Note that you should be <em>very careful</em> any time you use scripts like this, as data loss can happen where you least expect it. I use this script for clearing out development databases, but would never use it for production databases.</p>
<p>Anyway, on to the script.<br />
<span id="more-280"></span></p>
<pre class="brush: sql; ">

declare @sql varchar(max)
declare @tbl varchar(255)
declare @tblname varchar(255)

--dpecify the &quot;like&quot; clause for your tables here
--to match all tables, use &#039;%&#039;
set @tblname = &#039;%&#039;

--drop stored procedures
select name
into #procs
from sys.objects
where type = &#039;P&#039;
and name like @tblname

while (select count(*) from #procs) &gt; 0
begin
    select top 1 @tbl = name from #procs
    set @sql = &#039;drop procedure &#039; + @tbl
    exec (@sql)
    delete from #procs where name = @tbl
end

drop table #procs

--drop UDFs
select name
into #funcs
from sys.objects
where type in( &#039;TF&#039;, &#039;FN&#039; )
and name like @tblname

while (select count(*) from #funcs) &gt; 0
begin
    select top 1 @tbl = name from #funcs
    set @sql = &#039;drop function &#039; + @tbl
    exec (@sql)
    delete from #funcs where name = @tbl
end

drop table #funcs

--drop views
select name
into #views
from sys.objects
where type = &#039;V&#039;
and name like @tblname

while (select count(*) from #views) &gt; 0
begin
    select top 1 @tbl = name from #views
    set @sql = &#039;drop view &#039; + @tbl
    exec (@sql)
    delete from #views where name = @tbl
end

drop table #views

--drop constraints
select &#039;alter table &#039; + table_schema + &#039;.&#039; + table_name + &#039; drop constraint &#039; + constraint_name as query
into #constraints
from information_schema.table_constraints
where constraint_type = &#039;foreign key&#039;
and table_name like @tblname

while (select count(*) from #constraints) &gt; 0
begin
    select top 1 @sql = query from #constraints
    exec (@sql)
    delete from #constraints where query = @sql
end

drop table #constraints

--drop tables
select name
into #tables
from sys.objects
where type = &#039;U&#039;
and name like @tblname

while (select count(*) from #tables) &gt; 0
begin
    select top 1 @tbl = name from #tables
    set @sql = &#039;drop table &#039; + @tbl
    exec (@sql)
    delete from #tables where name = @tbl
end

drop table #tables

go
</pre>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=280&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2008/09/11/scripting-the-deletion-of-objects-in-a-sql-database-second-version/' addthis:title='Scripting the deletion of objects in a SQL database (second version) ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2008/09/11/scripting-the-deletion-of-objects-in-a-sql-database-second-version/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Remove anonymous users from ASP.Net Membership tables</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2008/08/07/remove-anonymous-users-from-aspnet-membership-tables/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2008/08/07/remove-anonymous-users-from-aspnet-membership-tables/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 18:53:47 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/?p=269</guid>
		<description><![CDATA[<p>If you use the <a href="http://weblogs.asp.net/scottgu/archive/2006/02/24/ASP.NET-2.0-Membership_2C00_-Roles_2C00_-Forms-Authentication_2C00_-and-Security-Resources-.aspx">ASP.Net membership tools</a>, have &#60;anonymousIdentification enabled="true" /&#62; specified in your Web.config, and get lots of anonymous visitors, it&#8217;s only a matter of time before your database grows. What&#8217;s filling it up is the countless user records for your anonymous users.</p>
<p>If you don&#8217;t need to track user and profile information for an anonymous user once they leave the site, you can delete the unneeded data by running a SQL script. The following script will delete from your membership tables all anonymous users whose last activity was more than 7 days ago.</p>


delete from aspnet_profile
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &#38;gt; 7
)

delete from aspnet_usersinroles
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &#38;gt; 7
)

delete from aspnet_membership
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &#38;gt; 7
)

delete from aspnet_personalizationperuser
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2008/08/07/remove-anonymous-users-from-aspnet-membership-tables/">Remove anonymous users from ASP.Net Membership tables</a></span>]]></description>
			<content:encoded><![CDATA[<p>If you use the <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fweblogs.asp.net%2Fscottgu%2Farchive%2F2006%2F02%2F24%2FASP.NET-2.0-Membership_2C00_-Roles_2C00_-Forms-Authentication_2C00_-and-Security-Resources-.aspx&sref=rss">ASP.Net membership tools</a>, have <code>&lt;anonymousIdentification enabled="true" /&gt;</code> specified in your Web.config, and get lots of anonymous visitors, it&#8217;s only a matter of time before your database grows. What&#8217;s filling it up is the countless user records for your anonymous users.</p>
<p>If you don&#8217;t need to track user and profile information for an anonymous user once they leave the site, you can delete the unneeded data by running a SQL script. The following script will delete from your membership tables all anonymous users whose last activity was more than 7 days ago.</p>
<pre class="brush: sql; ">

delete from aspnet_profile
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &amp;gt; 7
)

delete from aspnet_usersinroles
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &amp;gt; 7
)

delete from aspnet_membership
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &amp;gt; 7
)

delete from aspnet_personalizationperuser
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &amp;gt; 7
)

delete from aspnet_users
where userid in ( select userid from aspnet_users
where isanonymous = 1
and datediff(dd, lastactivitydate, getdate()) &amp;gt; 7
)
</pre>
<p>Doing this may be very important to those using a shared hosting plan that has limited SQL disk space, as those anonymous users can quickly eat up disk space. Since each row in aspnet_users takes up just over 1kb, having 1,000 anonymous users will eat up 1MB &#8212; something that adds up quick if you only have 250MB of SQL disk storage.</p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=269&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2008/08/07/remove-anonymous-users-from-aspnet-membership-tables/' addthis:title='Remove anonymous users from ASP.Net Membership tables ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2008/08/07/remove-anonymous-users-from-aspnet-membership-tables/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deleting all tables and constraints in a database</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 15:40:32 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/?p=268</guid>
		<description><![CDATA[<p>We all need to do it from time to time &#8212; erase a bunch of tables in a SQL database. Sure, you can do this through Enterprise Manager, one table at a time, or write a bunch of DROP TABLE statements, but when doing it this way, you also need to ensure all foreign key constraints (i.e. table dependencies) are dropped first.</p>
<p>There&#8217;s an easier way &#8212; the following script, which was derived from a few posts scattered around the Internet. (Sorry, it&#8217;s been a while, and I don&#8217;t remember what they were!)</p>
<p></p>


declare @sql varchar(max)
declare @tbl varchar(255)
declare @tblname varchar(255)

--Specify the &#34;like&#34; clause for your tables here
--to match all tables, use &#039;%&#039;
set @tblname = &#039;&#039;

select &#039;alter table &#039; + table_schema + &#039;.&#039; + table_name + &#039; drop constraint &#039; + constraint_name as query
into #constraints
from information_schema.table_constraints
where constraint_type = &#039;foreign key&#039;
and table_name like @tblname

while (select count(*) from #constraints) &#38;gt; 0
begin
select top 1 @sql = query from #constraints
exec (@sql)
delete from #constraints where query = @sql
end

drop table <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/">Deleting all tables and constraints in a database</a></span>]]></description>
			<content:encoded><![CDATA[<p>We all need to do it from time to time &#8212; erase a bunch of tables in a SQL database. Sure, you can do this through Enterprise Manager, one table at a time, or write a bunch of <code>DROP TABLE</code> statements, but when doing it this way, you also need to ensure all foreign key constraints (i.e. table dependencies) are dropped first.</p>
<p>There&#8217;s an easier way &#8212; the following script, which was derived from a few posts scattered around the Internet. (Sorry, it&#8217;s been a while, and I don&#8217;t remember what they were!)</p>
<p><span id="more-268"></span></p>
<pre class="brush: sql; ">

declare @sql varchar(max)
declare @tbl varchar(255)
declare @tblname varchar(255)

--Specify the &quot;like&quot; clause for your tables here
--to match all tables, use &#039;%&#039;
set @tblname = &#039;&#039;

select &#039;alter table &#039; + table_schema + &#039;.&#039; + table_name + &#039; drop constraint &#039; + constraint_name as query
into #constraints
from information_schema.table_constraints
where constraint_type = &#039;foreign key&#039;
and table_name like @tblname

while (select count(*) from #constraints) &amp;gt; 0
begin
select top 1 @sql = query from #constraints
exec (@sql)
delete from #constraints where query = @sql
end

drop table #constraints

select name
into #tables
from sys.objects
where type = &#039;U&#039;
and name like @tblname

while (select count(*) from #tables) &amp;gt; 0
begin
select top 1 @tbl = name from #tables
set @sql = &#039;drop table &#039; + @tbl
exec (@sql)
delete from #tables where name = @tbl
end

drop table #tables
go
</pre>
<p>Simply change the <code>set @tblname = ''</code> as needed &#8212; it&#8217;s used in a <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fms179859.aspx&sref=rss"><code>LIKE</code></a> statement to allow you to do these operations on a subset of tables. To run this script against all tables, use <code>set @tblname = '%'</code>.</p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=268&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/' addthis:title='Deleting all tables and constraints in a database ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2008/08/06/deleting-all-tables-and-constraints-in-a-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bad Programming: How not to use try/catch blocks</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2008/06/12/bad-programming-how-not-to-use-trycatch-blocks/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2008/06/12/bad-programming-how-not-to-use-trycatch-blocks/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 16:27:31 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bad programming]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/index.php/archive/2008/06/12/bad-programming-how-not-to-use-trycatch-blocks/</guid>
		<description><![CDATA[<p>I just stumbled across the following SQL 2005 code:</p>
	BEGIN TRY
		UPDATE [tabProgramSite]
		SET
			[Name] = @ProgramSiteName
		WHERE [ProgramSiteID] = @ProgramSiteId
	END TRY
	BEGIN CATCH
	END CATCH
<p>Nothing like catching an error&#8230; and doing nothing about it. I hope the user experience isn&#8217;t as robust.</p>
<a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2008/06/12/bad-programming-how-not-to-use-trycatch-blocks/">Bad Programming: How not to use try/catch blocks</a></span>]]></description>
			<content:encoded><![CDATA[<p>I just stumbled across the following SQL 2005 code:</p>
<pre>	BEGIN TRY
		UPDATE [tabProgramSite]
		SET
			[Name] = @ProgramSiteName
		WHERE [ProgramSiteID] = @ProgramSiteId
	END TRY
	BEGIN CATCH
	END CATCH</pre>
<p>Nothing like catching an error&#8230; and doing nothing about it. I hope the user experience isn&#8217;t as robust.</p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=254&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2008/06/12/bad-programming-how-not-to-use-trycatch-blocks/' addthis:title='Bad Programming: How not to use try/catch blocks ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2008/06/12/bad-programming-how-not-to-use-trycatch-blocks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Separating SQL script files generated by Microsoft SQL (by type)</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2008/06/03/separating-sql-script-files-generated-by-microsoft-sql-by-type/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2008/06/03/separating-sql-script-files-generated-by-microsoft-sql-by-type/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 19:37:58 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/index.php/archive/2008/06/03/separating-sql-script-files-generated-by-microsoft-sql-by-type/</guid>
		<description><![CDATA[<p>There&#8217;s one great feature in SQL: the &#8220;Generate Scripts&#8221; command. Unfortunately, it has one limitation: the default filenames of scripts look something like this:</p>
<blockquote><p>dbo.fnc_PlayerValue.UserDefinedFunction.sql
dbo.UserSelect.StoredProcedure.sql</p></blockquote>
<p>I&#8217;d much prefer the filenames to match the object name, without the owner (&#8216;dbo&#8217;) or object type. In other words, I&#8217;d prefer the above two files to look like this:</p>
<blockquote><p>UserDefinedFunction\fnc_PlayerValue.sql
StoredProcedure\UserSelect.sql</p></blockquote>
<p>How do we get from point A to point B without a lot of manual file copies and renames? We use <a href="http://commandwindows.com/batchfiles-iterating.htm">the FOR command</a>!</p>
<p>First, create a subdirectory for each object type (Table, StoredProcedure, UserDefinedFunction, View, Schema, Trigger, and User), then run the following from a command prompt.</p>
<blockquote>

for %i in (*.User.sql) do for /f "delims=., tokens=1-3" %j in ("%i") do move %i %k\%j.%l
for %i in (*.Schema.sql) do for /f "delims=., tokens=1-3" %j in ("%i") do move %i %k\%j.%l
for %i in (*.Trigger.sql) do for /f "delims=., tokens=1-3" %j in ("%i") do move %i %k\%j.%l
for %i in (*.sql) do for /f "delims=., tokens=1-4" %j in ("%i") do move %i %l\%k.%m
</blockquote>
<p>The command <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2008/06/03/separating-sql-script-files-generated-by-microsoft-sql-by-type/">Separating SQL script files generated by Microsoft SQL (by type)</a></span>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s one great feature in SQL: the &#8220;Generate Scripts&#8221; command. Unfortunately, it has one limitation: the default filenames of scripts look something like this:</p>
<blockquote><p>dbo.fnc_PlayerValue.UserDefinedFunction.sql<br />
dbo.UserSelect.StoredProcedure.sql</p></blockquote>
<p>I&#8217;d much prefer the filenames to match the object name, without the owner (&#8216;dbo&#8217;) or object type. In other words, I&#8217;d prefer the above two files to look like this:</p>
<blockquote><p>UserDefinedFunction\fnc_PlayerValue.sql<br />
StoredProcedure\UserSelect.sql</p></blockquote>
<p>How do we get from point A to point B without a lot of manual file copies and renames? We use <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fcommandwindows.com%2Fbatchfiles-iterating.htm&sref=rss">the FOR command</a>!</p>
<p>First, create a subdirectory for each object type (Table, StoredProcedure, UserDefinedFunction, View, Schema, Trigger, and User), then run the following from a command prompt.</p>
<blockquote>
<pre>
for %i in (*.User.sql) do for /f "delims=., tokens=1-3" %j in ("%i") do move %i %k\%j.%l
for %i in (*.Schema.sql) do for /f "delims=., tokens=1-3" %j in ("%i") do move %i %k\%j.%l
for %i in (*.Trigger.sql) do for /f "delims=., tokens=1-3" %j in ("%i") do move %i %k\%j.%l
for %i in (*.sql) do for /f "delims=., tokens=1-4" %j in ("%i") do move %i %l\%k.%m</pre>
</blockquote>
<p>The command above will look for each file with a *.sql extension in the current directory. For each of those files, it copies it to a directory based on the type of file, and ensures the new file only includes the object name and the .sql extension. So much cleaner now!</p>
<p>Note that this will not work if any folder in the full path to the SQL files has a period in it!</p>
<p><strong>Updated 2009.11.10 to support Trigger, User, and Schema scripts.</strong></p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=252&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2008/06/03/separating-sql-script-files-generated-by-microsoft-sql-by-type/' addthis:title='Separating SQL script files generated by Microsoft SQL (by type) ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2008/06/03/separating-sql-script-files-generated-by-microsoft-sql-by-type/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to use REPLACE() within NTEXT columns in SQL Server</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2008/02/27/how-to-use-replace-within-ntext-columns-in-sql-server/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2008/02/27/how-to-use-replace-within-ntext-columns-in-sql-server/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 21:10:30 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/index.php/archive/2008/02/27/how-to-use-replace-within-ntext-columns-in-sql-server/</guid>
		<description><![CDATA[<p>SQL has an incredibly useful function, REPLACE(), which replaces all occurrences of a specified string with another string, returning a new string. It works great with all forms of NCHAR and NVARCHAR fields. It does not, however, work with NTEXT fields.</p>
<p>Fear not &#8212; there&#8217;s an easy workaround, thanks to type-casting and SQL 2005&#8242;s NVARCHAR(max) datatype. Here&#8217;s the process in an nutshell.</p>

Cast the NTEXT field to the NVARCHAR(max) datatype using the CAST function.
Perform your REPLACE on the output of #1.
Cast the output of #2 back to NTEXT. (Not really required, but it does get us back to where we started.

<p>A simple SQL query illustrates this.</p>


select cast(replace(cast(myntext as nvarchar(max)),&#039;find&#039;,&#039;replace&#039;) as ntext)
from myntexttable

<p>If you&#8217;re using SQL 2000, you&#8217;re out of luck, as NVARCHAR(max) first appeared in SQL 2005. However, if your NTEXT field is less than 8000 characters, you can cast it to VARCHAR(8000) &#8212; the largest possible VARCHAR size &#8212; to accomplish the same.</p>
<p><em>[Note #1: This solution below will also work with TEXT <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2008/02/27/how-to-use-replace-within-ntext-columns-in-sql-server/">How to use REPLACE() within NTEXT columns in SQL Server</a></span>]]></description>
			<content:encoded><![CDATA[<p>SQL has an incredibly useful function, <code>REPLACE()</code>, which replaces all occurrences of a specified string with another string, returning a new string. It works great with all forms of <code>NCHAR</code> and <code>NVARCHAR</code> fields. It does not, however, work with <code>NTEXT</code> fields.</p>
<p>Fear not &#8212; there&#8217;s an easy workaround, thanks to type-casting and SQL 2005&#8242;s <code>NVARCHAR(max)</code> datatype. Here&#8217;s the process in an nutshell.</p>
<ol>
<li>Cast the <code>NTEXT</code> field to the <code>NVARCHAR(max)</code> datatype using the <code>CAST</code> function.</li>
<li>Perform your <code>REPLACE</code> on the output of #1.</li>
<li>Cast the output of #2 back to <code>NTEXT</code>. (Not really required, but it does get us back to where we started.</li>
</ol>
<p>A simple SQL query illustrates this.</p>
<pre class="brush: sql; ">

select cast(replace(cast(myntext as nvarchar(max)),&#039;find&#039;,&#039;replace&#039;) as ntext)
from myntexttable
</pre>
<p>If you&#8217;re using SQL 2000, you&#8217;re out of luck, as <code>NVARCHAR(max)</code> first appeared in SQL 2005. However, if your <code>NTEXT</code> field is less than 8000 characters, you can cast it to <code>VARCHAR(8000)</code> &#8212; the largest possible <code>VARCHAR</code> size &#8212; to accomplish the same.</p>
<p><em>[Note #1: This solution below will also work with <code>TEXT</code> fields. Simply replace <code>NTEXT</code> with <code>TEXT</code>, and <code>NVARCHAR</code> with <code>VARCHAR</code>.]</em></p>
<p><em>[Note #2: <code>NTEXT</code> fields are depreciated in SQL 2005 in favor of <code>NVARCHAR(max)</code>, so avoid using <code>NTEXT</code> and you'll avoid this problem altogether in the future.]</em></p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=226&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2008/02/27/how-to-use-replace-within-ntext-columns-in-sql-server/' addthis:title='How to use REPLACE() within NTEXT columns in SQL Server ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2008/02/27/how-to-use-replace-within-ntext-columns-in-sql-server/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Five simple rules for creating delimited text files</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2007/05/16/five-simple-rules-for-creating-delimited-text-files/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2007/05/16/five-simple-rules-for-creating-delimited-text-files/#comments</comments>
		<pubDate>Wed, 16 May 2007 15:02:46 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/index.php/archive/2007/05/16/five-simple-rules-for-creating-delimited-text-files/</guid>
		<description><![CDATA[<p>Here&#8217;s a few tips for those people who provide raw data in text files (think CSV files and the like).</p>

<strong>Surround all text fields in single quotes, even if a comma does not exist in a specific instance.</strong> By failing to do this, you lose field delimiter consistency on a row-by-row basis, forcing the contents of the field to be parsed separately (i.e. stripping the &#8220;optional&#8221; quotes).
<strong>Use consistent line endings.</strong> Pick one and stick with it for all your files. Use either (CR/LF), (LF), or (CR) &#8212; and use the same in all your files.
<strong>Put column headings in the first row only.</strong> This is more a convenience than a necessity. If you make your first row column headings, make sure it is only the first row.
<strong>Every row past the first should have an identical schema.</strong> Don&#8217;t try to be fancy and have different row types in one file. Each file should have the same number and sequence of columns.
<strong>Provide delimiters for all <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2007/05/16/five-simple-rules-for-creating-delimited-text-files/">Five simple rules for creating delimited text files</a></span>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a few tips for those people who provide raw data in text files (think CSV files and the like).</p>
<ol>
<li><strong>Surround all text fields in single quotes, even if a comma does not exist in a specific instance.</strong> By failing to do this, you lose field delimiter consistency on a row-by-row basis, forcing the contents of the field to be parsed separately (i.e. stripping the &#8220;optional&#8221; quotes).</li>
<li><strong>Use consistent line endings.</strong> Pick one and stick with it for all your files. Use either (CR/LF), (LF), or (CR) &#8212; and use the same in all your files.</li>
<li><strong>Put column headings in the first row only.</strong> This is more a convenience than a necessity. If you make your first row column headings, make sure it is only the first row.</li>
<li><strong>Every row past the first should have an identical schema.</strong> Don&#8217;t try to be fancy and have different row types in one file. Each file should have the same number and sequence of columns.</li>
<li><strong>Provide delimiters for all columns, even when a row does not have data for them.</strong> For example, in a comma-delimited file with five columns, if a row has data in only the first two columns, make sure the row ends with three commas. Failure to do so implies missing or incomplete data.</li>
</ol>
<p>When text files following these guidelines, I can write a script to import them into a SQL table (using BCP and a simple batch file) in a few minutes. Each guideline that is broken requires additional cleanup steps and more complex data import steps, and adds significant development (and debugging) time that shouldn&#8217;t be necessary.</p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=67&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2007/05/16/five-simple-rules-for-creating-delimited-text-files/' addthis:title='Five simple rules for creating delimited text files ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2007/05/16/five-simple-rules-for-creating-delimited-text-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically generate (partial) XML format files for BCP</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2007/05/08/automatically-generate-partial-xml-format-files-for-bcp/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2007/05/08/automatically-generate-partial-xml-format-files-for-bcp/#comments</comments>
		<pubDate>Tue, 08 May 2007 21:14:08 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.sidesofmarch.com/index.php/archive/2007/05/08/automatically-generate-partial-xml-format-files-for-bcp/</guid>
		<description><![CDATA[<p>I&#8217;ve been working with a lot of raw data files lately &#8212; data files that come in some delimited format which I must move into a SQL database. Most of the files are CSV files, and some of them have over 100 columns.</p>
<p>Using BCP to import CSV files into SQL is a pleasure. The only annoyance is writing those XML format files. Actually, the annoyance is not writing them, it&#8217;s going through the CSV files (which, of course, are undocumented) to determine what delimiters are used in each row.</p>
<p>Here&#8217;s a sample of what I mean:</p>
2934,128321,2782,"2007-04-32","Excluded",2321,,22
<p>Fortunately, most CSV files are consistent in their use of quotes, but going through dozens of columns to determine the terminators is a pain. The terminators in the above example aren&#8217;t just commas; they could also be quotes. Column three, for example, ends with a comma followed by a quote.</p>
<p>To generate the &#60;record&#62; section of my format files, I wrote the following script, which reads the first <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2007/05/08/automatically-generate-partial-xml-format-files-for-bcp/">Automatically generate (partial) XML format files for BCP</a></span>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working with a lot of raw data files lately &#8212; data files that come in some delimited format which I must move into a SQL database. Most of the files are CSV files, and some of them have over 100 columns.</p>
<p>Using BCP to import CSV files into SQL is a pleasure. The only annoyance is writing those XML format files. Actually, the annoyance is not writing them, it&#8217;s going through the CSV files (which, of course, are undocumented) to determine what delimiters are used in each row.</p>
<p>Here&#8217;s a sample of what I mean:</p>
<pre>2934,128321,2782,"2007-04-32","Excluded",2321,,22</pre>
<p>Fortunately, most CSV files are consistent in their use of quotes, but going through dozens of columns to determine the terminators is a pain. The terminators in the above example aren&#8217;t just commas; they could also be quotes. Column three, for example, ends with a comma followed by a quote.</p>
<p>To generate the <code>&lt;record&gt;</code> section of my format files, I wrote the following script, which reads the first line of a text file, finds each comma, determines if it is preceded or followed by a quote, and generates the appropriate XML.</p>
<pre class="brush: javascript; ">

//get filename
var args = WScript.Arguments;
if (args.length == 0)
{
	WScript.Echo(&#039;Usage: getdelims.vbs &lt;filename&gt;&#039;);
	WScript.Quit();
}

var filename = args(0);

//read file
var fso = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;);
var file = fso.OpenTextFile(filename,1);
var contents = file.ReadLine();
file.Close();
file = null;
fso = null;

//find commas
var cnt = 0;
for (var i = 1; i &lt; contents.length; i++)
{
	if ( contents.substr(i,1) != &#039;,&#039; ) continue;
	cnt++;
	delim = &quot;,&quot;;
	if ( contents.substr(i-1,1) == &#039;&quot;&#039; )
		delim = &#039;&amp;quot;,&#039;;
	if ( i+1 &lt; contents.length &amp;&amp; contents.substr(i+1,1) == &#039;&quot;&#039; )
		delim += &#039;&amp;quot;&#039;;
	WScript.Echo(&#039;\t&lt;FIELD ID=&quot;&#039; + cnt + &#039;&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;&#039; + delim + &#039;&quot; /&gt;&#039;);
}
</pre>
<p>The output can be copy/pasted right into your format file. The example content above would generate the following.</p>
<pre class="brush: xml; ">

        &lt;field ID=&quot;1&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;,&quot; /&gt;
        &lt;field ID=&quot;2&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;,&quot; /&gt;
        &lt;field ID=&quot;3&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;,&amp;quot;&quot; /&gt;
        &lt;field ID=&quot;4&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;&amp;quot;,&amp;quot;&quot; /&gt;
        &lt;field ID=&quot;5&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;&amp;quot;,&quot; /&gt;
        &lt;field ID=&quot;6&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;,&quot; /&gt;
        &lt;field ID=&quot;7&quot; xsi:type=&quot;CharTerm&quot; TERMINATOR=&quot;,&quot; /&gt;
</pre>
<p>A few minutes writing a script, and I won&#8217;t be looking at CSV files with too many columns ever again (at least, not for the reason of writing XML format files).</filename></p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=64&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2007/05/08/automatically-generate-partial-xml-format-files-for-bcp/' addthis:title='Automatically generate (partial) XML format files for BCP ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2007/05/08/automatically-generate-partial-xml-format-files-for-bcp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scripting SQL database builds</title>
		<link>http://www.sidesofmarch.com/index.php/archive/2007/04/03/scripting-sql-database-builds/</link>
		<comments>http://www.sidesofmarch.com/index.php/archive/2007/04/03/scripting-sql-database-builds/#comments</comments>
		<pubDate>Tue, 03 Apr 2007 13:30:12 +0000</pubDate>
		<dc:creator>brian</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://site366.mysite4now.com/compsims/sidesofmarch/index.php/archive/2007/04/03/scripting-sql-database-builds/</guid>
		<description><![CDATA[<p>A project I&#8217;m working on requires importing data from hundreds of megabytes of delimited text files into a staging database, then converting and migrating the data into an operations database. (Forgive the naming conventions. The &#8220;staging&#8221; database is used as an intermediary between the text files and the final database. The &#8220;operations&#8221; database is the one the application uses.)</p>
<p>What&#8217;s the best way to do automate this? Ideally, I need to be able to re-run the import at any time, preferably with a single command. The process should purge the staging database, rebuild tables (since schemas may change), reload all data, and run the necessary migration scripts. Since the final product is merely a web interface to the imported data, there is no harm in wiping and recreating everything from scratch, as there is no &#8220;user data&#8221; of note. (Actually there is, but it is isolated from this process.)</p>
<p>The solution I came up with used a series of SQL scripts executed using <span style="color:#777"> . . .<br /><br />&#8594; Read More: <a href="http://www.sidesofmarch.com/index.php/archive/2007/04/03/scripting-sql-database-builds/">Scripting SQL database builds</a></span>]]></description>
			<content:encoded><![CDATA[<p>A project I&#8217;m working on requires importing data from hundreds of megabytes of delimited text files into a staging database, then converting and migrating the data into an operations database. (Forgive the naming conventions. The &#8220;staging&#8221; database is used as an intermediary between the text files and the final database. The &#8220;operations&#8221; database is the one the application uses.)</p>
<p>What&#8217;s the best way to do automate this? Ideally, I need to be able to re-run the import at any time, preferably with a single command. The process should purge the staging database, rebuild tables (since schemas may change), reload all data, and run the necessary migration scripts. Since the final product is merely a web interface to the imported data, there is no harm in wiping and recreating everything from scratch, as there is no &#8220;user data&#8221; of note. (Actually there is, but it is isolated from this process.)</p>
<p>The solution I came up with used a series of SQL scripts executed using <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fmsdn2.microsoft.com%2Fen-us%2Flibrary%2Fms170207.aspx&sref=rss"><span style="font-family: Courier New">sqlcmd</span></a> (part of MS SQL 2005; use <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fmsdn2.microsoft.com%2Fen-us%2Flibrary%2Fms162806.aspx&sref=rss"><span style="font-family: Courier New">osql</span></a> for older versions) and data import tasks using <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fmsdn2.microsoft.com%2Fen-us%2Flibrary%2Fms162802.aspx&sref=rss"><span style="font-family: Courier New">bcp</span></a> (part of MS SQL), all tied together using batch files.<span id="more-21"></span></p>
<p>The script to build the staging table (which required use of sqlcmd and bcp) was broken down into four steps:</p>
<ol>
<li>Copy files from a source directory to a temporary working directory.</li>
<li>Clean up file formats.</li>
<li>Build tables from SQL scripts.</li>
<li>Import data using bcp.</li>
</ol>
<p><span style="font-weight: bold">Step 1: </span>The first step set working variables, ensured the working directory existed, and copied files.</p>
<pre style="margin-left: 40px">setlocal
set xsrc=C:devprojectdata
set dest=C:devprojecttrunkData_import
set scripts=C:devprojecttrunkData</pre>
<pre style="margin-left: 40px">@echo Preparing import directory...
if not exist %dest% md %dest%
del /q %dest%*.dat

@echo Copying files for import...
copy %src%players*.dat %dest% /y
copy %src%games*.dat %dest% /y
...</pre>
<p><span style="font-weight: bold">Step 2: </span>The files received need some tweaking to make importing easier, so I use a <a href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fgnuwin32.sourceforge.net%2Fpackages%2Fgsar.htm&sref=rss">gsar utility</a> for search-and-replace. Note the use of the <a style="font-family: Courier New" href="http://redirectingat.com?id=17923X751173&xs=1&url=http%3A%2F%2Fwww.microsoft.com%2Fresources%2Fdocumentation%2Fwindows%2Fxp%2Fall%2Fproddocs%2Fen-us%2Ffor.mspx&sref=rss">for</a> command, which allows you to repeat a command line based on all matching files in a directory (in this case, all *.dest files in the %dest% directory).</p>
<div style="margin-left: 40px">
<pre>@echo Cleaning up files for import...
for %%f in (%dest%*.dat) do gsar -o %%f -sNULL -r""""""</pre>
</div>
<p><span style="font-weight: bold">Steps 3 and 4:</span> Again, I use <span style="font-family: Courier New">for</span> loops to recursively create tables and import data.</p>
<pre style="margin-left: 40px">@echo Creating tables...
for %%f in (%root%tables*.sql) do sqlcmd -U user -P pass -S (local) -d database -i %%f
...

@echo Importing data...
for %%f in (%dest%games*.dat) do bcp db1.dbo.games in %%f -f games.xml -T -F 1 -m 1 -h "TABLOCK"
...</pre>
<p>That&#8217;s pretty much it. It&#8217;s nice to be able to click one batch file and automatically build and load data into databases.</p>
<img src="http://www.sidesofmarch.com/?ak_action=api_record_view&id=21&type=feed" alt="" /><div class="addthis_toolbox addthis_default_style addthis_32x32_style" addthis:url='http://www.sidesofmarch.com/index.php/archive/2007/04/03/scripting-sql-database-builds/' addthis:title='Scripting SQL database builds ' ><a class="addthis_button_preferred_1"></a><a class="addthis_button_preferred_2"></a><a class="addthis_button_preferred_3"></a><a class="addthis_button_preferred_4"></a><a class="addthis_button_compact"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.sidesofmarch.com/index.php/archive/2007/04/03/scripting-sql-database-builds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

