<?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>Never Say Never &#187; Script</title>
	<atom:link href="http://phelabaum.com/archive/tag/script/feed/" rel="self" type="application/rss+xml" />
	<link>http://phelabaum.com</link>
	<description>MS SQL Server Development</description>
	<lastBuildDate>Thu, 29 Sep 2011 02:20:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Tally Table &#8211; Character Date Validation</title>
		<link>http://phelabaum.com/archive/2009/12/tally-table-character-date-validation/</link>
		<comments>http://phelabaum.com/archive/2009/12/tally-table-character-date-validation/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 00:34:48 +0000</pubDate>
		<dc:creator>Seth Phelabaum</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Date Manipulation]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[String Manipulation]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Tally Table]]></category>

		<guid isPermaLink="false">http://phelabaum.com/archive/2009/12/tally-table-character-date-validation/</guid>
		<description><![CDATA[Tally (or numbers) tables are one of my favorite query writing tools.  Such a simple premise that can be applied to a wide variety of problems.   If you don&#8217;t know what they are, I&#8217;d recommend this article.   Here is one problem I&#8217;ve seen a few times now that you can use a Tally table to [...]]]></description>
			<content:encoded><![CDATA[<p>Tally (or numbers) tables are one of my favorite query writing tools.  Such a simple premise that can be applied to a wide variety of problems.   If you don&#8217;t know what they are, I&#8217;d recommend <a href="http://www.sqlservercentral.com/articles/T-SQL/62867/" target="_blank">this article</a>.   Here is one problem I&#8217;ve seen a few times now that you can use a Tally table to easily solve.  This is by no means the only way to do something like this, nor is it necessarily even the *best* way, but it is *a* way.</p>
<p><span style="text-decoration: underline;">The Problem:</span></p>
<p>You have a char/varchar column that holds dates in YYYYMMDD format.  You now need to cast these values to dates.  The problem is, with no validation on the column, some of these values aren&#8217;t actually valid dates and you get conversion errors.  You&#8217;d like to go through and identify anything that didn&#8217;t follow the pattern of YYYYMMDD or wasn&#8217;t a valid date so that it can be either fixed or removed.</p>
<p><span style="text-decoration: underline;">The Tally Solution:</span></p>
<p>The following query uses a Tally table to generate a range of valid dates that you can check your varchar field against.  The below version works in 2000+.  (You can just as easily use a CTE tally in 2005/2008)</p>
<div class="codecolorer-container sql mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">DECLARE</span> @StartDate datetime<br />
<span style="color: #993333; font-weight: bold;">DECLARE</span> @EndDate datetime<br />
<br />
<span style="color: #993333; font-weight: bold;">SET</span> @StartDate <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'19910101 00:00:00'</span><br />
<span style="color: #993333; font-weight: bold;">SET</span> @EndDate <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'20250101 00:00:00'</span><br />
<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> YourTable<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> vcdatecolumn <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">YEAR</span><span style="color: #66cc66;">&#40;</span>dateadd<span style="color: #66cc66;">&#40;</span>d<span style="color: #66cc66;">,</span>n<span style="color: #66cc66;">,</span>@StartDate<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">CHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span><br />
<span style="color: #993333; font-weight: bold;">RIGHT</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'0'</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>dateadd<span style="color: #66cc66;">&#40;</span>d<span style="color: #66cc66;">,</span>n<span style="color: #66cc66;">,</span>@StartDate<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span><br />
<span style="color: #993333; font-weight: bold;">RIGHT</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'0'</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>dateadd<span style="color: #66cc66;">&#40;</span>d<span style="color: #66cc66;">,</span>n<span style="color: #66cc66;">,</span>@StartDate<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> Tally<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> DATEADD<span style="color: #66cc66;">&#40;</span>d<span style="color: #66cc66;">,</span>n<span style="color: #66cc66;">,</span>@StartDate<span style="color: #66cc66;">&#41;</span> &amp;lt;<span style="color: #66cc66;">=</span> @EndDate<br />
<span style="color: #66cc66;">&#41;</span></div></div>
<p><span style="text-decoration: underline;">Other Methods:</span><br />
As mentioned, there are a lot of ways to do this.  Because ISDATE() jumps out as being such an easy one, I&#8217;ll mention a couple of the problems with using that method.  The main gap left is that some of the junk values (fairly common with this setup) like &#8217;9901&#8242; are valid dates according to ISDATE().  However, it is unlikely that this date is really supposed to be 9901/01/01.  You can add a length check, but then you run into &#8217;9901June&#8217; still being valid, etc. etc.  Using the Tally method, all of these are simply flagged as invalid and you can make up your mind about what to do with them once they&#8217;ve been identified.</p>
]]></content:encoded>
			<wfw:commentRss>http://phelabaum.com/archive/2009/12/tally-table-character-date-validation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

