<?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>Aaron Lowe &#187; T-SQL</title>
	<atom:link href="http://www.aaronlowe.net/archive/category/sql-server/t-sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aaronlowe.net</link>
	<description>SELECT my.Thoughts FROM Vendoran.dbo.Brain my</description>
	<lastBuildDate>Mon, 30 Jan 2012 19:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PASS Summit PreCon 2</title>
		<link>http://www.aaronlowe.net/archive/2011/10/pass-summit-precon-2/</link>
		<comments>http://www.aaronlowe.net/archive/2011/10/pass-summit-precon-2/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 18:26:06 +0000</pubDate>
		<dc:creator>Vendoran</dc:creator>
				<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[sqlpass]]></category>

		<guid isPermaLink="false">http://www.aaronlowe.net/archive/2011/10/pass-summit-precon-2/</guid>
		<description><![CDATA[Day 2 of the SQLPass Summit I attended Advanced T-SQL for SQL Server 2008 and Denali presented by Itzik Ben-Gan (twitter &#124; site), this was rated a 499 Session, so not for the faint of heart.&#160; For those of you that don’t know who Itzik is just take a look at this site and what [...]]]></description>
			<content:encoded><![CDATA[<p>Day 2 of the <a href="http://www.sqlpass.org/" target="_blank">SQLPass</a> Summit I attended Advanced T-SQL for SQL Server 2008 and Denali presented by Itzik Ben-Gan (<a href="http://twitter.com/#!/ItzikBenGan" target="_blank">twitter</a> | <a href="http://tsql.solidq.com/" target="_blank">site</a>), this was rated a 499 Session, so not for the faint of heart.&#160; For those of you that don’t know who Itzik is just take a look at this site and what books he authors. In short he’s one of the premier T-SQL experts.</p>
<p>Here was the Agenda:</p>
<ul>
<li>APPLY Magic </li>
<li>Grouping Sets </li>
<li>TOP / OFFSET-FETCH </li>
<li>Sequences </li>
<li>Windows Functions </li>
<li>Intervals </li>
<li>Other T-SQL Improvements in Denali </li>
</ul>
<p>First a truism – SQL is a set based language, the concepts and logic that exist are designed for set based activities.&#160; He also went over how the Query is written:</p>
<ol>
<li>SELECT </li>
<li>FROM </li>
<li>WHERE </li>
<li>GROUP BY </li>
<li>HAVING </li>
<li>ORDER BY </li>
</ol>
<p>vs. how it’s processed:</p>
<ol>
<li>FROM </li>
<li>WHERE </li>
<li>GROUP BY </li>
<li>HAVING </li>
<li>SELECT </li>
<li>ORDER BY </li>
</ol>
<p>The session was, as you can imagine, pretty intense.&#160; Itzik obviously loves what he was talking about and is very passionate.&#160; He talked about how to improve standard SQL as well for migrations between other SQL implementations.</p>
<p>As far as some of the new features of T-SQL in Denali that was mentioned:</p>
<ul>
<li>OFFSET / FETCH (think paging)</li>
<li>Sequences (independent identity objects that can be referenced and keep proper seeding)</li>
</ul>
<p><a href="http://www.aaronlowe.net/wp-content/uploads/2011/10/Image.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Image" border="0" alt="Image" src="http://www.aaronlowe.net/wp-content/uploads/2011/10/Image_thumb.png" width="244" height="189" /></a></p>
<ul>
<li>Windows Functions (this set functions) – these have been expanded tremendously to include things like LAG, LEAD, FIRST_VALUE, LAST_VALUE, distribution functions (PERCENT_RANK, etc.), ROWS and RANGE&#160; </li>
<li>Conversion – PARSE, TRY, TRY_CONVERT (returns NULL if can’t convert), TRY_PARSE</li>
<li>Date and Time – EOMONTH (end of month), DATEFROMPARTS and similar functions to build date, time and datetime data from different parts</li>
<li>Logical – CHOOSE, IIF – these were added to improve Access migrations</li>
<li>String – CONCAT this is used for string concatenation, similar to the + operator, however it will automatically convert NULL to to strings; FORMAT – this brings in .NET format functionality, however it’s slower than native SQL formatting (probably because it utilized CLR behind the scene)</li>
<li>Mathematical – LOG now supports the ability to indicate the base</li>
<li>Improved Error Handling – THROW, this finally allows us re-throw the original error to be bubbled up.&#160; Until now we’ve had to utilize user errors</li>
<li>EXECUTE WITH RESULT SETS – This allows us to call an SP and guarantee the shape of result set.&#160; We submit an expected result set shape which if the return set doesn’t match SQL will try to implicitly convert to, however it could fail if it can’t return what is specified.</li>
<li>Metadata discovery &#8211; removes the SET FMTONLY – this allows us to interrogate and return the metadata </li>
<li>FORCESCAN and FORCESEEK – this allows us to force an index seek or index scan for a particular query</li>
</ul>
<p>Another great session and it’s cool to see the advancements being made within T-SQL.&#160; More to come later.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlowe.net/archive/2011/10/pass-summit-precon-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Case Solved: SQL Function Design for Performance</title>
		<link>http://www.aaronlowe.net/archive/2011/10/case-solved-sql-function-design-for-performance/</link>
		<comments>http://www.aaronlowe.net/archive/2011/10/case-solved-sql-function-design-for-performance/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 13:00:23 +0000</pubDate>
		<dc:creator>Vendoran</dc:creator>
				<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.aaronlowe.net/?p=279</guid>
		<description><![CDATA[This is the solution post for – The Case of the Time it takes to Convert Time Zones So did you figure it out?  The case asked 2 questions: What was the problem? How did it happen? What was the problem? So lets walk through how it would convert a datetime from CT to UTC.  [...]]]></description>
			<content:encoded><![CDATA[<p>This is the solution post for – <a href="http://www.aaronlowe.net/?p=277" target="_blank">The Case of the Time it takes to Convert Time Zones</a></p>
<p>So did you figure it out?  The case asked 2 questions:</p>
<ol>
<li>What was the problem?</li>
<li>How did it happen?</li>
</ol>
<p><strong>What was the problem?</strong></p>
<p>So lets walk through how it would convert a datetime from CT to UTC.  We’d issue a SELECT dbo.GetDateOffset(@MyDate, 1); Next the function builds 2 in memory table variables – 1 for getting the start date of DST for the given year and 1 for getting the end date of DST for the given year.  It then compares @MyDate to see if it’s within the DST range and then offsets accordingly. Now increase that to 50,000 calls, and we have some serious performance issues.</p>
<p><strong>How did it happen?</strong></p>
<p>It happened because of 2 reasons.  First, the mantra of “I’ll get it to work and then worry about performance”.  Secondly, and more importantly, I didn’t spend time thinking about the problem – you know creating a design.  I figured it’s just a small function, not a huge system and therefore no big deal.  However what is a huge system made up of?  Oh yeah, that’s right, small functions and other pieces of code.  Had I taken the time to actually design it I would have written it better.</p>
<p><strong>The Solution</strong></p>
<p>So let’s actually think about the problem again, and let’s begin by looking at Daylight Savings, but look at it a different way:</p>
<p>2005 and Before:</p>
<ul>
<li>Begins the first Sunday in April clocks are set ahead one hour, so 2:00 a.m. becomes 3:00 a.m.</li>
<li>Ends the last Sunday in October clocks are set back one hour, so 2:00 a.m. becomes 1:00 a.m.</li>
</ul>
<p>2006 and After:</p>
<ul>
<li>Ends the second Sunday in March clocks are set ahead one hour, so 2:00 a.m. becomes 3:00 a.m.</li>
<li>Ends the first Sunday in November clocks are set back one hour, so 2:00 a.m. becomes 1:00 a.m.</li>
</ul>
<p>That means for 10 months out of the year we know exactly what to do without any other investigation!  For 2005 and before November, December, January, February, March I need to offset by 6, while May, June, July, August, September I need to offset by 5.  For 2006 and after I shift accordingly.    Awesome!  However while that drastically reduces the amount of times the GetStartDST and GetEndDST is called, those functions are still called to decide the start and end date for April and October of 2005 and before as well as March and November 2006 and after.</p>
<p>We’re doing so well, let’s continue to break it down, and start with the first one.  How can we figure out the first Sunday of a April in 2005.  We know the date and we know the month, how about if we just get the weekday of the first of the month and then just offset?  The idea being that if the first of the month is a Monday, then we know the first Sunday of the month is the 7th, also if the first of the month is a Saturday we know the first Sunday of the month is the 2nd.  We don’t need to use an in memory table at all!!</p>
<p>So without further adieu, here was my final function:</p>
<pre class="brush: sql;" style="width: 1163px; height: 388px;">CREATE FUNCTION dbo.GetOffsetDate
(
    @Date datetime
    , @Sign bit
    --0 = UTC to CT
    --1 = CT to UTC
)
RETURNS datetime
AS
BEGIN
    IF @Date = CAST('1753-01-01 00:00:00.000' as datetime) AND @Sign = 0 RETURN @Date;
    IF @Date = CAST('9999-12-31 23:59:59.997' as datetime) AND @Sign = 1 RETURN @Date;

    DECLARE
        @Time tinyint
        , @Datetimeoffset datetimeoffset
        , @BeginDST datetime
        , @EndDST datetime
        , @ReturnDate datetime;

    SET @Time = 0;
    SELECT @Datetimeoffset = CAST(@Date as datetimeoffset);

    IF YEAR(@Date) &gt;= 2006
        BEGIN
            IF MONTH(@Date) IN (1,2,12) SET @Time = 1; --Not in DST
            IF MONTH(@Date) IN (4,5,6,7,8,9,10) SET @Time = 2; --In DST
        END;
    ELSE
        BEGIN
            IF MONTH(@Date) IN (1,2,3,11,12) SET @Time = 1; --Not in DST
            IF MONTH(@Date) IN (5,6,7,8,9) SET @Time = 2; --In DST
        END;

    --Still Need to determin if DST or Not, either a starting or ending month
    IF @Time = 0
        BEGIN
            DECLARE
                @DSTDate date
                , @WeekDay int;

            IF YEAR(@Date) &gt;= 2006
                BEGIN
                    --2006 and forward second Sunday in March, clocks are set ahead - 2:00 a.m. becomes 3:00 a.m.
                    SET @DSTDate = CAST(CAST(YEAR(@Date) as varchar(4)) + '-03-01' as Date);
                    SET
                        @WeekDay =
                            CASE DATEPART(WEEKDAY, @DSTDate)
                                WHEN 1 THEN 8
                                WHEN 2 THEN 14
                                WHEN 3 THEN 13
                                WHEN 4 THEN 12
                                WHEN 5 THEN 11
                                WHEN 6 THEN 10
                                WHEN 7 THEN 9
                            END;
                    SELECT @BeginDST = CAST(CAST(@DSTDate as varchar) + ' 02:00:00' as datetime);

                    --2005 and before first Sunday in April, clocks are set ahead - 2:00 a.m. becomes 3:00 a.m.
                    SET @DSTDate = CAST(CAST(YEAR(@Date) as varchar(4)) + '-04-01' as Date);
                    SET
                        @WeekDay =
                            CASE DATEPART(WEEKDAY, @DSTDate)
                                WHEN 1 THEN 1
                                WHEN 2 THEN 7
                                WHEN 3 THEN 6
                                WHEN 4 THEN 5
                                WHEN 5 THEN 4
                                WHEN 6 THEN 3
                                WHEN 7 THEN 2
                            END;
                    SELECT @EndDST = CAST(CAST(@DSTDate as varchar) + ' 02:00:00' as datetime);
                END;
            ELSE
                BEGIN
                    --2006 first Sunday in November, clocks are set back - 2:00 a.m. becomes 1:00 a.m.
                    SET @DSTDate = CAST(CAST(YEAR(@Date) as varchar(4)) + '-11-01' as Date);
                    SET
                        @WeekDay =
                            CASE DATEPART(WEEKDAY, @DSTDate)
                                WHEN 1 THEN 1
                                WHEN 2 THEN 7
                                WHEN 3 THEN 6
                                WHEN 4 THEN 5
                                WHEN 5 THEN 4
                                WHEN 6 THEN 3
                                WHEN 7 THEN 2
                            END;
                    SELECT @BeginDST = CAST(CAST(@DSTDate as varchar) + ' 02:00:00' as datetime);

                    --2005 last Sunday in October, clocks are set back - 2:00 a.m. becomes 1:00 a.m.
                    SET @DSTDate = CAST(CAST(YEAR(@Date) as varchar(4)) + '-10-31' as Date);
                    SET
                        @WeekDay =
                            Case DATEPART(WEEKDAY, @DSTDate)
                                WHEN 1 THEN 31
                                WHEN 2 THEN 30
                                WHEN 3 THEN 29
                                WHEN 4 THEN 28
                                WHEN 5 THEN 27
                                WHEN 6 THEN 26
                                WHEN 7 THEN 25
                            END;
                    SELECT @EndDST = CAST(CAST(@DSTDate as varchar) + ' 02:00:00' as datetime);
                END;
        END;

    SELECT
        @ReturnDate =
            CASE
                --UTC to CT
                WHEN @Sign = 0
                    THEN
                        CASE
                            WHEN (@Datetimeoffset BETWEEN @BeginDST AND @EndDST) OR (@Time = 2)
                                --UTC to CDT
                                THEN
                                    SWITCHOFFSET(@Datetimeoffset, '-05:00')
                                --UTC to CST
                                ELSE
                                    SWITCHOFFSET(@Datetimeoffset, '-06:00')
                        END
                --CT to UTC
                ELSE
                    CASE
                        WHEN (@Datetimeoffset BETWEEN @BeginDST AND @EndDST) OR (@Time = 2)
                            --CDT to UTC
                            THEN
                                SWITCHOFFSET (@Datetimeoffset, '+05:00')
                            --CST to UTC
                            ELSE
                                SWITCHOFFSET (@Datetimeoffset, '+06:00')
                    END
            END;

    RETURN @ReturnDate;
END</pre>
<p>As you’ll see it really was a rewrite, not just “fixed” for performance.</p>
<p>So what did we learn?  Performance is not just a bolt-on at the end and always, always, always, think about the problem before you try code a solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlowe.net/archive/2011/10/case-solved-sql-function-design-for-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Case of the Time it takes to Convert Time Zones</title>
		<link>http://www.aaronlowe.net/archive/2011/10/the-case-of-the-time-it-takes-to-convert-time-zones/</link>
		<comments>http://www.aaronlowe.net/archive/2011/10/the-case-of-the-time-it-takes-to-convert-time-zones/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 13:00:15 +0000</pubDate>
		<dc:creator>Vendoran</dc:creator>
				<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.aaronlowe.net/?p=277</guid>
		<description><![CDATA[Full Disclosure – I loved Encyclopedia Brown as a kid. A couple weeks ago I was tasked with a the problem of unifying datetime fields within disparate databases that were loaded into a single data warehouse.  The challenge was that vendor product A recorded all time in UTC while vendor product B recorded all time [...]]]></description>
			<content:encoded><![CDATA[<p><em>Full Disclosure – I loved <a href="http://en.wikipedia.org/wiki/Encyclopedia_Brown" target="_blank">Encyclopedia Brown</a> as a kid.</em></p>
<p>A couple weeks ago I was tasked with a the problem of unifying datetime fields within disparate databases that were loaded into a single data warehouse.  The challenge was that vendor product A recorded all time in UTC while vendor product B recorded all time in CT.  CT being the composite of CDT and CST.  With all SQL servers being in UTC (therefore applying the difference of GETDATE() and GETUTCDATE() was not possible), the primary challenge was determining when the datetime needed offset by 5 hours and when it needed offset by 6 hours.</p>
<p>Daylight Savings Begins:</p>
<ul>
<li>2005 and before the first Sunday in April clocks are set ahead one hour, so 2:00 a.m. becomes 3:00 a.m.</li>
<li>2006 and forward the second Sunday in March clocks are set ahead one hour, so 2:00 a.m. becomes 3:00 a.m.</li>
</ul>
<p>Daylight Savings Ends:</p>
<ul>
<li>2005 and before the last Sunday in October clocks are set back one hour, so 2:00 a.m. becomes 1:00 a.m.</li>
<li>2006 and after the first Sunday in November clocks are set back one hour, so 2:00 a.m. becomes 1:00 a.m.</li>
</ul>
<p>Next I opened up SSMS and starting writing TSQL code.  Wanting to be as efficient as possible I figured I’d create a single function that could convert either direction UTC to CT or CT to UTC, the function would return the converted datetime.</p>
<p>So the process:</p>
<ol>
<li>Pass the datetime to the function</li>
<li>Determine the beginning and end of Daylight savings for that year</li>
<li>if the datetime is between the start and end date of Daylight savings offset by 5, if not offset by 6, the offset bit parameter determines whether to add or subtract</li>
</ol>
<p>I ended up with these 3 functions:</p>
<ul>
<li>dbo.GetOffsetDate – this function took in a datetime and a bit field to indicate direction (UTC to CT or CT to UTC)</li>
<li>dbo.GetDTStart – this functions was called from dbo.GetOffsetDate and took a datetime to determine the beginning of Daylight Savings time for that year</li>
<li>dbo.GetDTEnd– this functions was called from dbo.GetOffsetDate and took a datetime to determine the ending of Daylight Savings time for that year</li>
</ul>
<p>GetOffsetDate was fairly straightforward, took in parameters called dbo.GetDTStart and dbo.GetDSTEnd and then performed an embedded case statement to determine if the date was in between DSTStart and DTSEnd or if it was an add or subtract operation.</p>
<pre class="brush: sql;" style="width: 1166px; height: 226px;">CREATE FUNCTION dbo.GetOffsetDate
(
    @Date datetime
    , @Sign bit
    --1 = CT to UTC
    --0 = UTC to CT
)
RETURNS datetime
AS
BEGIN
    DECLARE
        @BeginDST datetime
        , @EndDST datetime
        , @Datetimeoffset datetimeoffset
        , @ReturnDate datetime;

    SELECT @Datetimeoffset = CAST(@Date as datetimeoffset);

    SELECT
        @BeginDST = dbo.GETDSTStart(@Date)
        , @EndDST = dbo.GETDSTEnd(@Date)

    SELECT
        @ReturnDate =
        CASE
            WHEN @Datetimeoffset BETWEEN @BeginDST AND @EndDST
                THEN
                    CASE
                        WHEN @Sign = 1
                            THEN
                                SWITCHOFFSET(@Datetimeoffset, '+05:00')
                            ELSE
                                SWITCHOFFSET (@Datetimeoffset, '-05:00')
                    END
            ELSE
                CASE
                    WHEN @Sign = 0
                        THEN
                            SWITCHOFFSET(@Datetimeoffset, '+06:00')
                        ELSE
                            SWITCHOFFSET (@Datetimeoffset, '-05:00')
                END
        END;

    RETURN @ReturnDate;
END</pre>
<p>The real magic as they say was how it was determining the first Sunday in April, second Sunday in March, last Sunday in October and first Sunday in November.   So passing in a date I created a table variable and inserted 31 rows (no month has more than 31 days).  I then inserted dates beginning with the first of the appropriate month (March, April, October or November) for all 31 rows.  I then generated a ROW_NUMBER over the Sundays in that month and took the appropriate numbered Sunday (first, second or last – last I generated a ROW_NUMBER using DESC and grabbed the first).</p>
<pre class="brush: sql;" style="width: 1168px; height: 206px;">CREATE FUNCTION dbo.GETDSTStart
(
    @Date datetime
)
RETURNS datetime
AS
BEGIN
    --2005 and before first Sunday in April, clocks are set ahead one hour at 2:00 a.m. becomes 3:00 a.m.
    --2006 and forward second Sunday in March, clocks are set ahead one hour at 2:00 a.m. becomes 3:00 a.m. 

    DECLARE
        @BeginDSTDate date
        , @BeginDST datetime;
    DECLARE @Begin table (pkID int NOT NULL IDENTITY(1,1), DT date NULL);

    IF YEAR(@Date) &gt;= 2006
        BEGIN
            INSERT INTO @Begin DEFAULT VALUES
            WHILE SCOPE_IDENTITY() &lt; 31
                INSERT INTO @Begin DEFAULT VALUES;

            UPDATE
                @Begin
            SET
                DT = DATEADD(Day, pkID-1, cast(CAST(YEAR(@Date) as varchar(4)) + '-03-01' AS Date));

            SELECT
                @BeginDSTDate = DT
            FROM
                (
                SELECT
                    DT
                    , ROW_NUMBER() OVER(ORDER BY pkID ASC) AS [RowNumber]
                FROM
                    @Begin
                WHERE
                    ISNULL(DATEPART(Weekday, DT), 0) = 1
                ) d
            WHERE
                d.RowNumber = 2;
        END
    ELSE
        BEGIN
            INSERT INTO @Begin DEFAULT VALUES
            WHILE SCOPE_IDENTITY() &lt; 30
                INSERT INTO @Begin DEFAULT VALUES;

            UPDATE
                @Begin
            SET
                DT = DATEADD(Day, pkID-1, cast(CAST(YEAR(@Date) as varchar(4)) + '-04-01' AS Date));

            SELECT
                @BeginDSTDate = DT
            FROM
                (
                SELECT
                    DT
                    , ROW_NUMBER() OVER(ORDER BY pkID ASC) AS [RowNumber]
                FROM
                    @Begin
                WHERE
                    ISNULL(DATEPART(Weekday, DT), 0) = 1
                ) d
            WHERE
                d.RowNumber = 1;
        END

    SELECT
        @BeginDST = CAST(CAST(@BeginDSTDate as varchar) + ' 02:00:00' as datetime);

    RETURN @BeginDST;
END</pre>
<pre class="brush: sql;" style="width: 1167px; height: 217px;">CREATE FUNCTION dbo.GETDSTEnd
(
    @Date datetime
)
RETURNS datetime
AS
BEGIN
    --2005 last Sunday in October, clocks are set back one hour at 2:00 a.m. becomes 1:00 a.m.
    --2006 first Sunday in November, clocks are set back one hour at 2:00 a.m. becomes 1:00 a.m. 

    DECLARE
        @EndDSTDate date
        , @EndDST datetime;
    DECLARE @End table (pkID int NOT NULL IDENTITY(1,1), DT date NULL);

    IF YEAR(@Date) &gt;= 2006
        BEGIN
            INSERT INTO @End DEFAULT VALUES
            WHILE SCOPE_IDENTITY() &lt; 30
                INSERT INTO @End DEFAULT VALUES;

            UPDATE
                @End
            SET
                DT = DATEADD(Day, pkID-1, cast(CAST(YEAR(@Date) as varchar(4)) + '-11-01' AS Date));

            SELECT
                @EndDSTDate = DT
            FROM
                (
                SELECT
                    DT
                    , ROW_NUMBER() OVER(ORDER BY pkID ASC) AS [RowNumber]
                FROM
                    @End
                WHERE
                    ISNULL(DATEPART(Weekday, DT), 0) = 1
                ) d
            WHERE
                d.RowNumber = 1;
        END
    ELSE
        BEGIN
            INSERT INTO @End DEFAULT VALUES
            WHILE SCOPE_IDENTITY() &lt; 31
                INSERT INTO @End DEFAULT VALUES;

            UPDATE
                @End
            SET
                DT = DATEADD(Day, pkID-1, cast(CAST(YEAR(@Date) as varchar(4)) + '-10-01' AS Date));

            SELECT
                @EndDSTDate = DT
            FROM
                (
                SELECT
                    DT
                    , ROW_NUMBER() OVER(ORDER BY pkID DESC) AS [RowNumber]
                FROM
                    @End
                WHERE
                    ISNULL(DATEPART(Weekday, DT), 0) = 1
                ) d
            WHERE
                d.RowNumber = 1;
        END
    SELECT
        @EndDST = CAST(CAST(@EndDSTDate as varchar) + ' 02:00:00' as datetime);

    RETURN @EndDST;
END</pre>
<p>Now that it worked, I threw it into my SSIS package at which point the ETL dropped from about a minute to 25!!.  Unacceptable.  I started looking at the code trying to find improvements to no avail.  And then it dawned on me not only what the problem was, but more importantly why it happened.  I quickly resolved the problem and learned from why it happened.  Within the hour I was able to get an accurate and performant solutions.  What was the problem?  How did it happen?</p>
<p>Tune into the next post to find out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlowe.net/archive/2011/10/the-case-of-the-time-it-takes-to-convert-time-zones/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ISNUMERIC maybe…</title>
		<link>http://www.aaronlowe.net/archive/2009/09/isnumeric-maybe%e2%80%a6/</link>
		<comments>http://www.aaronlowe.net/archive/2009/09/isnumeric-maybe%e2%80%a6/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 10:00:00 +0000</pubDate>
		<dc:creator>Vendoran</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">/post/2009/09/30/ISNUMERIC-maybee280a6.aspx</guid>
		<description><![CDATA[So the other day I was working on a T-SQL query that I was using to take data from generic data types and insert it into a strongly typed table.&#160; One of the columns was moving from an nvarchar(255) to an decimal data type.&#160; As some of the rows had character data in it, I [...]]]></description>
			<content:encoded><![CDATA[<p>So the other day I was working on a T-SQL query that I was using to take data from generic data types and insert it into a strongly typed table.&nbsp; One of the columns was moving from an nvarchar(255) to an decimal data type.&nbsp; As some of the rows had character data in it, I wrote something like this:</p>
<pre class="brush: sql;">CASE ISNUMERIC(Col1)
    WHEN 1 THEN CAST(Col1 as decimal(9,4))
    ELSE NULL
END as Col1</pre>
<p>However when I ran the query, I received this error:</p>
<p><span style="font-family: cou; color: #ff0000; font-size: x-small;">Error converting data type nvarchar to numeric.</span></p>
<p>It took me awhile to figure this one out as you can see I&rdquo;m using ISNUMERIC to check before I convert it to a number, seems pretty straight forward, so what&rsquo;s the bid deal?</p>
<p>The big deal is that I needed to read the manual&hellip;according to the ISNUMERIC function in <a href="http://msdn.microsoft.com/en-us/library/ms186272.aspx" target="_blank">BOL</a>:</p>
<p><span style="font-family: cou; font-size: x-small;">ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see <a href="http://msdn.microsoft.com/en-us/library/ms188688.aspx">Using Monetary Data</a>.</span></p>
<p>It turned out I had a row that had a value of a single decimal point and no numbers which caused the problem.&nbsp; So remember, understand what the functions you use actually do, not what you think they do and test!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlowe.net/archive/2009/09/isnumeric-maybe%e2%80%a6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Did you know? SQL Server 2008 includes Transact-SQL Debugger</title>
		<link>http://www.aaronlowe.net/archive/2008/06/did-you-know-sql-server-2008-includes-transact-sql-debugger/</link>
		<comments>http://www.aaronlowe.net/archive/2008/06/did-you-know-sql-server-2008-includes-transact-sql-debugger/#comments</comments>
		<pubDate>Sat, 14 Jun 2008 01:39:35 +0000</pubDate>
		<dc:creator>Vendoran</dc:creator>
				<category><![CDATA[2008]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">/post/2008/06/14/Did-you-know-SQL-Server-2008-includes-Transact-SQL-Debugger.aspx</guid>
		<description><![CDATA[The Transact-SQL debugger in SQL Server Management Studio enables you to find errors in Transact-SQL scripts, stored procedures, triggers, and functions by observing their run-time behavior. You can start the debugger when you are using the Database Engine Query Editor window. By using the Transact-SQL debugger, you can do the following: Step through the Transact-SQL [...]]]></description>
			<content:encoded><![CDATA[<p><span class="sbmLink"></span>
<p><i>The Transact-SQL debugger in SQL Server Management Studio enables you to find errors in Transact-SQL scripts, stored procedures, triggers, and functions by observing their run-time behavior. You can start the debugger when you are using the Database Engine Query Editor window. </i></p>
<p><i></i></p>
<p><i>By using the Transact-SQL debugger, you can do the following:</i> </p>
<p><i></i></p>
<ul>
<li><i>Step through the Transact-SQL statements in the editor line by line, or set breakpoints to stop at specific lines.</i> </li>
<li><i>Step into or over Transact-SQL stored procedures, functions, or triggers that are run by the code in the editor window.</i> </li>
<li><i>Watch the values that are assigned to variables, and observe system objects such as the call stack and threads.&#160; </i></li>
</ul>
<p>Check out a screencast about the new T-SQL Debugger in SQL Server 2008 via MSN Video below, or if you prefer <a href="http://www.youtube.com/watch?v=618LE_FZCxI" target="_blank">Youtube</a> or <a href="http://cid-a1aa2222a8b0305c.skydrive.live.com/self.aspx/Public/Screencasts/ss2008%7C_dyn14%7C_t-sql%7C_debugger.wmv" target="_blank">download</a>.</p>
<div class="wlWriterSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:1291f541-7874-4ebb-a34e-3b8cd586b76f" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<div><embed pluginspage="http://macromedia.com/go/getflashplayer" src="http://images.video.msn.com/flash/soapbox1_1.swf" width="432" height="364" type="application/x-shockwave-flash" flashvars="c=v&amp;v=b4af876b-d796-412d-b9f2-dad3f9845195&amp;from=writer" wmode="transparent" quality="high" /></div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlowe.net/archive/2008/06/did-you-know-sql-server-2008-includes-transact-sql-debugger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

