<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlservernation.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>How Tos</title><link>http://sqlservernation.com/blogs/howtos/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Create a system stored procedure</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/10/29/create-a-system-stored-procedure.aspx</link><pubDate>Thu, 29 Oct 2009 23:28:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:311</guid><dc:creator>TimChapman</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=311</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/10/29/create-a-system-stored-procedure.aspx#comments</comments><description>&lt;p&gt;A system stored procedure is a proc that is stored in the master database that&amp;nbsp; you can run in the context of other databases on the instance.&amp;nbsp; For example, sp_msforeachtable is an example of a system stored procedure.&amp;nbsp; You can run this procedure in any database on the instance and it will loop through the tables in the database and issue a command against each.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;As an example, here is a stored procedure I wrote when SQL Server 2005 first came out.&amp;nbsp; This procedure uses a dynamic management view to recurse through any blocking connections and indicates the connection that is doing the blocking along w/ the blocking statement.&amp;nbsp; Making this a system stored procedure allows you to have the procedure in a centralized location, but with the advantage of being able to run it from any database on the instance.&amp;nbsp; &lt;/p&gt;
&lt;pre style="line-height:14px;background-color:#eee;width:100%;font-family:Andale Mono, Lucida Console, Monaco, fixed, monospace;color:#000000;font-size:12px;overflow:auto;border:#999999 1px dashed;padding:5px;"&gt;&lt;code&gt;USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*********************************************************************************************
*  Procedure Name:  dbo.sp_Blocking
*  Author:  Tim Chapman
***********************************************************************************************/
CREATE PROCEDURE [dbo].[sp_Blocking]
AS
BEGIN
    IF OBJECT_ID(&amp;#39;tempdb..#Processes&amp;#39;) IS NOT NULL
        DROP TABLE #Processes

    SELECT 
        s.spid, BlockingSPID = s.blocked, DatabaseName = DB_NAME(s.dbid),
        s.program_name, s.loginame, ObjectName = OBJECT_NAME(objectid, s.dbid), 
        Definition = CAST(text AS VARCHAR(MAX)), StatementBeginTime = last_batch
    INTO #Processes
    FROM 
        sys.sysprocesses s
        CROSS APPLY sys.dm_exec_sql_text (sql_handle)
    WHERE 
        s.spid &amp;gt; 50;

    WITH Blocking
    (
        SPID, BlockingSPID, BlockingObject, BlockingStatement, RowNo, LevelRow, 
        StatementBeginTime, BlockingStatementBeginTime
    ) 
    AS
    (
        --//BASE CASE FOR QUERY
        SELECT 
            s.SPID , s.BlockingSPID, s.ObjectName, s.Definition, ROW_NUMBER() OVER(ORDER BY s.SPID), 0 AS LevelRow, 
            s1.StatementBeginTime, s.StatementBeginTime
        FROM 
            #Processes s
            JOIN #Processes s1 ON s.SPID = s1.BlockingSPID
        WHERE 
            s.BlockingSPID = 0
        UNION ALL
        --//RECURSIVE CASE
        SELECT 
            r.SPID,  r.BlockingSPID, r.ObjectName, r.Definition, d.RowNo, d.LevelRow + 1, 
            d.BlockingStatementBeginTime, r.StatementBeginTime
        FROM 
            #Processes r
            JOIN Blocking d ON r.BlockingSPID = d.SPID
        WHERE 
            r.BlockingSPID &amp;gt; 0
    )
    SELECT 
        SPID, 
        BlockingSPID, 
        BlockingObject, 
        RowNo, 
        LevelRow, 
        BlockingStatementBeginTime, 
        StatementBeginTime, 
        PotentialBlockingDurationS = ABS(DATEDIFF(ms, StatementBeginTime, BlockingStatementBeginTime))/1000.0
    FROM Blocking
    ORDER BY 
        RowNo, LevelRow
END
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Once my procedure has been created in the master database, I can use a system stored procedure to mark the procedure as a system stored procedure.&amp;nbsp; :)&lt;/p&gt;
&lt;pre style="line-height:14px;background-color:#eee;width:100%;font-family:Andale Mono, Lucida Console, Monaco, fixed, monospace;color:#000000;font-size:12px;overflow:auto;border:#999999 1px dashed;padding:5px;"&gt;&lt;code&gt;EXECUTE sp_ms_marksystemobject &amp;#39;sp_Blocking&amp;#39;    
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From there, I can run the following in any database and it will produce any blocking procedures.&amp;nbsp; &lt;/p&gt;
&lt;pre style="line-height:14px;background-color:#eee;width:100%;font-family:Andale Mono, Lucida Console, Monaco, fixed, monospace;color:#000000;font-size:12px;overflow:auto;border:#999999 1px dashed;padding:5px;"&gt;&lt;code&gt;EXECUTE sp_Blocking
&lt;/code&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=311" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/master+database/default.aspx">master database</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/dynamic+management+view/default.aspx">dynamic management view</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/system+stored+procedure/default.aspx">system stored procedure</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/DMV/default.aspx">DMV</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/sql+server/default.aspx">sql server</category></item><item><title>run_duration in SQL Server system tables</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/10/26/run-duration-in-sql-server-system-tables.aspx</link><pubDate>Mon, 26 Oct 2009 15:31:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:310</guid><dc:creator>Feodor Georgiev</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=310</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/10/26/run-duration-in-sql-server-system-tables.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you are interested in the run duration of
the jobs on your SQL Server you would most likely query the system tables
sysjobs and&amp;nbsp;sysjobhistory from the msdb database&amp;nbsp;in a manner similar
to this:&lt;/p&gt;
&lt;p&gt;select name&lt;/p&gt;
&lt;p&gt;,enabled&lt;/p&gt;
&lt;p&gt;,run_status&lt;/p&gt;
&lt;p&gt;,run_date&lt;/p&gt;
&lt;p&gt;,run_time&lt;/p&gt;
&lt;p&gt;,run_duration&lt;/p&gt;
&lt;p&gt;from msdb.dbo.sysjobs sj&lt;/p&gt;
&lt;p&gt;join msdb.dbo.sysjobhistory sjh&lt;/p&gt;
&lt;p&gt;&amp;nbsp;on sj.job_id
= sjh.&amp;nbsp;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
What is interesting (and yes, it could be misleading!) is that the run_duration
is presented by the following formula:&lt;br /&gt;
&lt;br /&gt;
(hours*10000) + (minutes*100) + seconds&lt;br /&gt;
&lt;br /&gt;
The bottom line is: do NOT think that the run duration is converted to seconds.
Here is an example: if a job has a duration of 102950, this means that the job
executed in 10 hours, 29 minutes and 50 seconds.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=310" width="1" height="1"&gt;</description></item><item><title>sp_MSForEachDB - leashed and unleashed</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/10/09/sp-msforeachdb-leashed-and-unleashed.aspx</link><pubDate>Fri, 09 Oct 2009 09:56:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:299</guid><dc:creator>Feodor Georgiev</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=299</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/10/09/sp-msforeachdb-leashed-and-unleashed.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;First things first&lt;/span&gt; - a few words on Microsoft undocumented
procedures (and tools): it is this simple - USE THEM WITH CAUTION. There are
several out there, and they are all great. If you compare sp_who (documented)
with sp_who2 (UN-documented) you will see the advantages.&lt;br /&gt;
&lt;br /&gt;
In the case of sp_MSForEachDB (UN-documented), there are several warnings I
would like to bring to your attention:&lt;br /&gt;
1. Do not abuse it, since it is a global cursor.&lt;br /&gt;
2. UN-documented means that if something goes wrong, you will not be getting
support&lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration:underline;"&gt;To the point:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
sp_MSForEachDB accepts several parameters: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;@RETURN_VALUE&lt;/b&gt; is an integer that is set to the return value
associated with SP &lt;br /&gt;
&lt;b&gt;@command1&lt;/b&gt; is a nvarchar(2000) field for specifying the
first command to run against each database &lt;br /&gt;
&lt;b&gt;@replacechar&lt;/b&gt; is a nchar(1) field that represents the
character used in the commands you are executing that will be replaced with the
database name prior to being executed &lt;br /&gt;
&lt;b&gt;@command2&lt;/b&gt; is a nvarchar(2000) field for specifying the
second command to run against each database &lt;br /&gt;
&lt;b&gt;@command3&lt;/b&gt; is a nvarchar(2000) field for specifying the
third command to run against each database &lt;br /&gt;
&lt;b&gt;@precommand&lt;/b&gt; is a nvarchar(2000) field for specifying a
command to be run prior to processing any commands (@command1, @command2,
@command3) against any databases &lt;br /&gt;
&lt;b&gt;@postcommand&lt;/b&gt; is a nvarchar(2000) field for specifying a
command to be run after all the commands against all databases have been
processed. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration:underline;"&gt;Example:&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;exec dbo.sp_msForEachDb @command1=&amp;#39;SELECT DB_NAME(DB_ID(&amp;#39;&amp;#39;?&amp;#39;&amp;#39;)) AS DatabaseName&amp;#39;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
So far all is clear. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration:underline;"&gt;Here come the trick questions:&lt;/span&gt; How do I get to filter out some of the
databases? Does this procedure always have to run for ALL databases? &lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration:underline;"&gt;Answers:&lt;/span&gt; Yes - we can filter out some databases. Here is how:&lt;br /&gt;
&lt;br /&gt;
For example, we know that the system databases have id from 1 to 4. So, if we
were able to run the procedure under a condition of &amp;quot;database id &amp;gt;
4&amp;quot;, then we are set. HOW?&lt;/p&gt;
&lt;p&gt;exec dbo.sp_msForEachDb @command1=&amp;#39;IF DB_ID(&amp;#39;&amp;#39;?&amp;#39;&amp;#39;) &amp;gt; 4 BEGIN select
DB_NAME(DB_ID(&amp;#39;&amp;#39;?&amp;#39;&amp;#39;)) AS DatabaseName END&amp;#39;&lt;/p&gt;
&lt;p&gt;Good. And to bring it even further:&lt;/p&gt;
&lt;p&gt;exec dbo.sp_msForEachDb @command1=&amp;#39;IF DB_ID(&amp;#39;&amp;#39;?&amp;#39;&amp;#39;) in
(1,3,5,7) BEGIN select DB_NAME(DB_ID(&amp;#39;&amp;#39;?&amp;#39;&amp;#39;)) AS DatabaseName END&amp;#39;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
And so on...&lt;br /&gt;
&lt;br /&gt;
&lt;span style="text-decoration:underline;"&gt;Bottom line: &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Think about this:&amp;nbsp;BI (Business Intelligence) tools give similar
functionality. In SQL Server we have &amp;quot;Maintenance Plans&amp;quot; GUI which is
the essential functionality needed to create packages which run towards any set
of databases. &lt;br /&gt;
Furthermore, if you would like to be elaborate, then you would use the BI tools
(SSIS in particular) which give endless possibilities for loops, variable
mapping, conditional task flows, and so on.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=299" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/stored+procedures/default.aspx">stored procedures</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/parameter/default.aspx">parameter</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Intermediate+SQL/default.aspx">Intermediate SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/sp_5F00_MSForEachDB/default.aspx">sp_MSForEachDB</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Business+Intelligence/default.aspx">Business Intelligence</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/undocumented+procedures/default.aspx">undocumented procedures</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/filter/default.aspx">filter</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/parameters/default.aspx">parameters</category></item><item><title>Determining Age through T-SQL</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/04/22/determining-age-through-t-sql.aspx</link><pubDate>Wed, 22 Apr 2009 14:52:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:179</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=179</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/04/22/determining-age-through-t-sql.aspx#comments</comments><description>&lt;p&gt;Sometimes it is necessary to calculate a person&amp;#39;s age.&amp;nbsp; I&amp;#39;ve seen people use a simple datediff on YEAR but that is not sufficient.&amp;nbsp; The reason why that is not sufficient is because it ONLY evaluates a difference on the YEAR value of the date.&amp;nbsp; So that means from December 31, 2008 to January 1, 2009 it would return 1.&amp;nbsp; Obviously that&amp;#39;s not correct.&amp;nbsp; You have to also compensate for the day of the year.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;There are a couple of ways this can be done.&amp;nbsp; You can do inline SQL to calculate the value all the time, but the calculation takes a bit of code so it won&amp;#39;t make reading it very easy.&amp;nbsp; I prefer to use a User Defined Function.&lt;/p&gt;
&lt;p&gt;In this user defined function the first thing we do is determine the difference in years.&amp;nbsp; This is where most procedure I&amp;#39;ve seen stop.&amp;nbsp; The next thing we do is add the value, stored in @Age, to the @BirthDate variable.&amp;nbsp; This makes the year of the @BirthDate value the same year as the @AsOfDate.&amp;nbsp; This is important because now we can do a simple &amp;gt; calculation.&amp;nbsp; If @BirthDate hasn&amp;#39;t come yet, then your age hasn&amp;#39;t increased yet.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function [dbo].[fn_GetAgeAsOf] (@BirthDate datetime, @AsOfDate datetime)&lt;br /&gt;returns int&lt;br /&gt;AS&lt;br /&gt;begin&lt;br /&gt;declare @Age   smallint&lt;br /&gt;set @age=datediff(yy, @birthdate,@asofdate)&lt;br /&gt;set @birthdate = dateadd(yy, @age, @birthdate)&lt;br /&gt;if @birthdate&amp;gt;@AsOfDate&lt;br /&gt;  set @Age=@Age-1&lt;br /&gt;return @age&lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The function above will work, even when you are calculating age in a leap year.&amp;nbsp; The below function, shows how using a simple datepart(dy,@Birthdate) &amp;gt; datepart(dy,@AsOfDate) will not work.&amp;nbsp; The reason it won&amp;#39;t work is the February 29 (during a leap year) and March 1 (during a non-leap year) both have the &amp;quot;Day of the Year&amp;quot; value of 60.&amp;nbsp; This will throw off the calculation for all dates after February.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#ff0000;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;&lt;b&gt;WARNING!!!&lt;/b&gt; This is not the function we are suggesting to use.  It is merely to show you why it doesn&amp;#39;t work.&lt;/code&gt;&lt;/pre&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function [dbo].[fn_GetAgeAsOf3] (@BirthDate datetime, @AsOfDate datetime)&lt;br /&gt;returns int&lt;br /&gt;AS&lt;br /&gt;begin&lt;br /&gt;declare @Age   smallint&lt;br /&gt;select @age=datediff(yy, @birthdate,@asofdate)&lt;br /&gt;if datepart(dy,@birthDate)&amp;gt;datepart(dy,@AsOfDate)&lt;br /&gt;  set @Age=@Age-1&lt;br /&gt;return @age&lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s run a couple of scripts with these two methods to show ow they work when spanning a leap year both with the leap year being selected as the date and March 1 being selected.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;select [dbo].[fn_GetAgeAsOf3](&amp;#39;2007-03-01&amp;#39;,&amp;#39;2008-02-29&amp;#39;),[dbo].[fn_GetAgeAsOf](&amp;#39;2007-03-01&amp;#39;,&amp;#39;2008-02-29&amp;#39;)&lt;br /&gt;select [dbo].[fn_GetAgeAsOf3](&amp;#39;2007-03-01&amp;#39;,&amp;#39;2008-03-01&amp;#39;),[dbo].[fn_GetAgeAsOf](&amp;#39;2007-03-01&amp;#39;,&amp;#39;2008-03-01&amp;#39;)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Below is the cleanup scripts for this exercise.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;if object_id(&amp;#39;[dbo].[fn_GetAgeAsOf]&amp;#39;) is not null
     drop function [dbo].[fn_GetAgeAsOf]
if object_id(&amp;#39;[dbo].[fn_GetAgeAsOf3]&amp;#39;) is not null
     drop function [dbo].[fn_GetAgeAsOf3]

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope that you find this useful and understand now how it can be a little more complicated than the simple solution when doing calculations in SQL Server.&amp;nbsp; To use the fn_AgeAsOf function to determine the current age, simply pass the current date as the @AsOfDate parameter.&amp;nbsp; Be mindful that if you simply pass in GETDATE() without stripping the time component, you can run into problems with the times being different and not doing a straight day calculation.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=179" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category></item><item><title>How to determine the Sunday of a given week!</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/04/06/how-to-determine-the-sunday-of-a-given-week.aspx</link><pubDate>Mon, 06 Apr 2009 15:40:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:176</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=176</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/04/06/how-to-determine-the-sunday-of-a-given-week.aspx#comments</comments><description>&lt;p&gt;Sometimes it is necessary for reporting purposes to query data for a caldendar week.&amp;nbsp; When doing so, us the the datepart function to retrieve the weeknum will not work because if a week spans more than one year it will only return the data for the same year.&amp;nbsp; For example, January 1, 2009 is a Thursday.&amp;nbsp; So the only dates that are in Week one of 2009 are January 1-3 (Thursday-Saturday).&amp;nbsp; So how would you include from Sunday forward?&amp;nbsp; The below function will help you.&lt;/p&gt;
&lt;p&gt;This function will return, for a given @InputDate, the Sunday directly preceeding it.&amp;nbsp; If the supplied @InputDate is a Sunday, it will return itself.&amp;nbsp; This function also returns only the DATE portion, stripping the time.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the function as well as a couple of sample calls.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;Oops, We&amp;#39;ve found a bug.  We are temporarily removing this function while we fix it.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There you have it.&amp;nbsp; Now if you need to run a query against all data from a table where the created_dttm is in the week of January 1, 2009.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;declare @Sunday datetime&lt;br /&gt;set @Sunday = dbo.fn_SundayOfWeek (&amp;#39;2009-01-01&amp;#39;)&lt;br /&gt;&lt;br /&gt;select * from SomeTable&lt;br /&gt;where created_dttm &amp;gt;= @Sunday &lt;br /&gt;  and created_Dttm &amp;lt; @Sunday-7&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The above query says to return all records whose created_dttm is between the Sunday before and the Saturday after, January 1, 2009.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope you found this useful.&amp;nbsp; Check back soon to see what other useful utility scripts we may have provided.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=176" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/scalar+valued+function/default.aspx">scalar valued function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category></item><item><title>Splitting a string into a table of characters</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/24/splitting-a-string-into-a-table-of-characters.aspx</link><pubDate>Wed, 25 Mar 2009 03:55:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:161</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=161</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/24/splitting-a-string-into-a-table-of-characters.aspx#comments</comments><description>&lt;p&gt;Sometimes you may not be able to see the characters in your data in SQL Server Mangement Studio (or another application).&amp;nbsp; This simple function will allow you to pass an input string in, and it will return the individual characters as rows from a Table Valued Function.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;First the code:&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;if object_id(&amp;#39;[dbo].[fn_CharsToTable]&amp;#39;) is not null&lt;br /&gt;     drop function [dbo].[fn_CharsToTable]&lt;br /&gt;go&lt;br /&gt;create function [dbo].[fn_CharsToTable](@InputString varchar(max))&lt;br /&gt;returns @Values TABLE&lt;br /&gt;     (position      int not null primary key clustered&lt;br /&gt;     ,theNChar      char(1)&lt;br /&gt;     )&lt;br /&gt;as&lt;br /&gt;/************************************************************&lt;br /&gt;*&lt;br /&gt;*    Author:        Brandon Galderisi&lt;br /&gt;*    Last modified: 25-Mar-2009&lt;br /&gt;*    Purpose:       splits an input string (@InputString) &lt;br /&gt;*                   into a table of single characters.&lt;br /&gt;*    &lt;br /&gt;*&lt;br /&gt;*************************************************************/&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;insert into @Values (position,theNChar)&lt;br /&gt;select n, substring(@InputString, n,1)&lt;br /&gt;from    dbo.vw_Nums&lt;br /&gt;where   n &amp;lt;= datalength(@InputString)&lt;br /&gt;order by n&lt;br /&gt;               &lt;br /&gt;return&lt;br /&gt;end&lt;br /&gt;/*&lt;br /&gt;-- The purpose of vw_Nums is if the source database does not have a numbers table.  This view (vw_nums)&lt;br /&gt;-- will allow the parsing of up to 4 billion+ character strings with the above function.  Whether a static&lt;br /&gt;-- table or this view is used for fn_DelimitedToTable, it can only split a string as long as the source &lt;br /&gt;-- numbers table.&lt;br /&gt;Requires a nunbers table or this view:&lt;br /&gt;create view vw_Nums&lt;br /&gt;as&lt;br /&gt;with   cte0 as (select 1 as c union all select 1), &lt;br /&gt;       cte1 as (select 1 as c from cte0 a, cte0 b), &lt;br /&gt;       cte2 as (select 1 as c from cte1 a, cte1 b), &lt;br /&gt;       cte3 as (select 1 as c from cte2 a, cte2 b), &lt;br /&gt;       cte4 as (select 1 as c from cte3 a, cte3 b), &lt;br /&gt;       cte5 as (select 1 as c from cte4 a, cte4 b), &lt;br /&gt;       nums as (select row_number() over (order by c) as n from cte5)&lt;br /&gt;       select n from nums &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Sample Usage:&lt;br /&gt;select * from [dbo].[fn_CharsToTable](&amp;#39;a|%25basdf|%25c|%25d&amp;#39;)&lt;br /&gt;select theValue from [dbo].[fn_CharsToTable](&amp;#39;a&amp;#39;)&lt;br /&gt;select * from [dbo].[fn_CharsToTable](&amp;#39;a basdf c d&amp;#39;)&lt;br /&gt;&lt;br /&gt;select * from [dbo].[fn_CharsToTable](&amp;#39;a|%25b&lt;br /&gt;asdf|%25c|%25d&amp;#39;)*/&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Using the function is simple.&amp;nbsp; You simply select from it like any other &lt;a title="Table Valued Functions" href="http://sqlservernation.com/blogs/howtos/archive/2009/03/07/table-valued-functions.aspx"&gt;Table Valued Function&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;select position,theNChar,ascii(thenChar) as &amp;#39;AsciiValue&amp;#39; from dbo.fn_charstotable(&amp;#39;hello, my name is Brandon&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The result will be the position of the character within the string, the character itself (if it&amp;#39;s not printable, you won&amp;#39;t see it), and the ASCII value of the character.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Splitting+a+string+into+a+table+of+characters/res1.png"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Splitting+a+string+into+a+table+of+characters/res1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The below is a unicode version of the same code:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;if object_id(&amp;#39;[dbo].[fn_CharsToTable]&amp;#39;) is not null
     drop function [dbo].[fn_CharsToTable]
go
create function [dbo].[fn_CharsToTable](@InputString nvarchar(max))
returns @Values TABLE
     (position      int not null primary key clustered
     ,theNChar      nchar(1)
     )
as
/************************************************************
*
*    Author:        Brandon Galderisi
*    Last modified: 25-Mar-2009
*    Purpose:       splits an input string (@InputString) 
*                   into a table of single characters.
*    
*
*************************************************************/
begin

insert into @Values (position,theNChar)
select n, substring(@InputString, n,1)
from    dbo.vw_Nums
where   n &amp;lt;= datalength(@InputString)/2
order by n
               
return
end
/*
-- The purpose of vw_Nums is if the source database does not have a numbers table.  This view (vw_nums)
-- will allow the parsing of up to 4 billion+ character strings with the above function.  Whether a static
-- table or this view is used for fn_DelimitedToTable, it can only split a string as long as the source 
-- numbers table.
Requires a nunbers table or this view:
create view vw_Nums
as
with   cte0 as (select 1 as c union all select 1), 
       cte1 as (select 1 as c from cte0 a, cte0 b), 
       cte2 as (select 1 as c from cte1 a, cte1 b), 
       cte3 as (select 1 as c from cte2 a, cte2 b), 
       cte4 as (select 1 as c from cte3 a, cte3 b), 
       cte5 as (select 1 as c from cte4 a, cte4 b), 
       nums as (select row_number() over (order by c) as n from cte5)
       select n from nums 
 
 
 
Sample Usage:
select * from [dbo].[fn_CharsToTable](&amp;#39;a%25basdf%25c%25d&amp;#39;)
select theValue from [dbo].[fn_CharsToTable](&amp;#39;a&amp;#39;)
select * from [dbo].[fn_CharsToTable](&amp;#39;a basdf c d&amp;#39;)

select * from [dbo].[fn_CharsToTable](&amp;#39;a%25b
asdf25c%25d&amp;#39;)*/
GO

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The usage of the function is the same, except instead of the ASCII() function, you would use the UNICODE() function.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;select position,theNChar,unicode(thenChar) as &amp;#39;AsciiValue&amp;#39; from dbo.fn_charstotable(&amp;#39;hello, my name is Brandon&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=161" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Intermediate+SQL/default.aspx">Intermediate SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/table+valued+function/default.aspx">table valued function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Advanced+SQL/default.aspx">Advanced SQL</category></item><item><title>Updating values in one table with values from another table</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/19/updating-values-in-one-table-with-values-from-another-table.aspx</link><pubDate>Thu, 19 Mar 2009 21:24:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:143</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=143</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/19/updating-values-in-one-table-with-values-from-another-table.aspx#comments</comments><description>&lt;p&gt;Sometimes, it is necessary to update a field in one table, with information from another table.&amp;nbsp; In this article, I will go over with you a few different methods for doing this.&amp;nbsp; At the bottom there is a link to download the entire SQL script used in this post.&lt;/p&gt;
&lt;p&gt;The first thing that we will do is create a few temporary tables to test with.&amp;nbsp; We will be loading these temporary tables, intentionally leaving the count columns in the #Employers table NULL because after each update we will set them back to NULL to verify that each update statement works.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create table #Employers&lt;br /&gt;     (employer_id             int primary key clustered&lt;br /&gt;     ,employer_name           nvarchar(50) not null unique&lt;br /&gt;     ,history_employee_count  int null&lt;br /&gt;     ,current_employee_count  int null&lt;br /&gt;     )&lt;br /&gt;go&lt;br /&gt;create table #Employees&lt;br /&gt;     (employee_id             int primary key clustered&lt;br /&gt;     ,employee_fname          nvarchar(50) not null&lt;br /&gt;     ,employee_lname          nvarchar(50) not null&lt;br /&gt;     )&lt;br /&gt;go&lt;br /&gt;create table #Employment&lt;br /&gt;     (employment_id           int identity primary key clustered&lt;br /&gt;     ,employee_id             int not null&lt;br /&gt;     ,employer_id             int not null&lt;br /&gt;     ,start_date              datetime not null&lt;br /&gt;     ,end_date                datetime null&lt;br /&gt;     )&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next we will load the tables with sample data.&amp;nbsp; This sample data will load 7 &amp;quot;fictional&amp;quot; employers, 8 fictional employees and map those employees to employers&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;insert into #Employers (employer_id,employer_name) &lt;br /&gt;     values(1,N&amp;#39;Acme Anvil Co.&amp;#39;)&lt;br /&gt;insert into #Employers (employer_id,employer_name) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(2,N&amp;#39;Kwik-E-Mart&amp;#39;)&lt;br /&gt;insert into #Employers (employer_id,employer_name) &lt;br /&gt;     values(3,N&amp;#39;The Android&amp;#39;&amp;#39;s Dungeon &amp;amp; Baseball Card Shop&amp;#39;)&lt;br /&gt;insert into #Employers (employer_id,employer_name) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(4,N&amp;#39;Happy-Go-Lucky Toy Factory&amp;#39;)&lt;br /&gt;insert into #Employers (employer_id,employer_name) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(5,N&amp;#39;SQL Server Nation&amp;#39;)&lt;br /&gt;insert into #Employers (employer_id,employer_name) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(6,N&amp;#39;ABC Co.&amp;#39;)&lt;br /&gt;insert into #Employers (employer_id,employer_name) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(7,N&amp;#39;XYZ Co.&amp;#39;)&lt;br /&gt;go&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(1,N&amp;#39;Apu&amp;#39;,N&amp;#39;Nahasapeemapetilon&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(2,N&amp;#39;Sanjay&amp;#39;,N&amp;#39;Nahasapeemapetilon&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(3,N&amp;#39;Jeff&amp;#39;,N&amp;#39;Albertson&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(4,N&amp;#39;Peter&amp;#39;,N&amp;#39;Griffin&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(5,N&amp;#39;Jonathon&amp;#39;,N&amp;#39;Weed&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(6,N&amp;#39;The&amp;#39;,N&amp;#39;Roadrunner&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(7,N&amp;#39;Brandon&amp;#39;,N&amp;#39;Galderisi&amp;#39;)&lt;br /&gt;insert into #Employees (employee_id,employee_fname,employee_lname) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(8,N&amp;#39;Tim&amp;#39;,N&amp;#39;Chapman&amp;#39;)&lt;br /&gt;go&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(1,2,&amp;#39;1989-12-17&amp;#39;,null)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(2,2,&amp;#39;1989-12-17&amp;#39;,null)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(3,3,&amp;#39;1989-12-17&amp;#39;,null)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(4,4,&amp;#39;1999-01-31&amp;#39;,&amp;#39;2002-02-14&amp;#39;)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;     &lt;/code&gt;&lt;code&gt;values(5,4,&amp;#39;1999-01-31&amp;#39;,&amp;#39;2002-02-14&amp;#39;)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(6,1,&amp;#39;1959-01-01&amp;#39;,&amp;#39;1989-12-31&amp;#39;)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(7,5,&amp;#39;2009-03-04&amp;#39;,null)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(8,5,&amp;#39;2009-03-04&amp;#39;,null)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;     &lt;/code&gt;&lt;code&gt;values(7,6,&amp;#39;2007-11-28&amp;#39;,null)&lt;br /&gt;insert into #Employment(employee_id,employer_id,start_date,end_date) &lt;/code&gt;&lt;code&gt;&lt;br /&gt;     &lt;/code&gt;&lt;code&gt;values(8,7,&amp;#39;2008-06-01&amp;#39;,null)&lt;br /&gt;go&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now that we have sample data to work with, let&amp;#39;s go over the various methods for performing these updates.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The first method that we will use is the correlated sub-select.&amp;nbsp; If you are familiar with sub-selects, both correlated and non-correlated, then this will be somewhat easy to understand.&amp;nbsp; But just in case, I&amp;#39;ll explain how this works.&amp;nbsp; A sub-select is a select statement that returns a single value to be used in a select statement.&amp;nbsp; The sub-select is correlated because it refers to a table that exists solely outside of the sub-select and is used to determine the value returned by the sub-select.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;update #employers&lt;br /&gt;set   history_employee_count = &lt;br /&gt;          (select count(distinct employee_id) &lt;br /&gt;           from #employment &lt;br /&gt;           where employer_id = #employers.employer_id&lt;br /&gt;          )&lt;br /&gt;     ,current_employee_count = &lt;br /&gt;          (select count(distinct employee_id) &lt;br /&gt;           from #employment &lt;br /&gt;           where employer_id = #employers.employer_id &lt;br /&gt;             and start_date &amp;lt;= getdate() &lt;br /&gt;             and (end_date &amp;gt; getdate() &lt;br /&gt;                  or &lt;br /&gt;                  end_date is null&lt;br /&gt;                 )&lt;br /&gt;          )&lt;br /&gt;&lt;br /&gt;go&lt;br /&gt;select * from #Employers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see, the counts accurately represent the historical, and current employee counts for each company.&amp;nbsp; Our goal, will be that each result set be identical to what you see below since this is the accurate result.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Updating+values+in+one+table+with+values+from+another+table/res1.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Updating+values+in+one+table+with+values+from+another+table/res1.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The next method that can be used in this situation is a JOIN to a derived table.&amp;nbsp; If you are not familiar with them, a derived table is a select statement wrapped in parentheses that returns more than one column.&amp;nbsp; One of the columns returned from the derived table is used to JOIN back to the table to be updated and the other is the value that will be used to update #Employers.&amp;nbsp; In this case, we use individual JOIN statements to retrieve each value for the #Employers table.&amp;nbsp; You will that the results of this select statement are identical to the first one.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;update #employers&lt;br /&gt;set   history_employee_count = null&lt;br /&gt;     ,current_employee_count = null&lt;br /&gt;go&lt;br /&gt;update #employers&lt;br /&gt;set   history_employee_count = isnull(hec.history_employee_count,0)&lt;br /&gt;     ,current_employee_count = isnull(hcc.current_employee_count,0)&lt;br /&gt;from #employers&lt;br /&gt;  left join &lt;br /&gt;     (select employer_id, &lt;br /&gt;      count(distinct employee_id) history_employee_count &lt;br /&gt;      from #employment &lt;br /&gt;      group by employer_id&lt;br /&gt;     ) hec&lt;br /&gt;    on #employers.employer_id = hec.employer_id&lt;br /&gt;  left join&lt;br /&gt;     (select employer_id, &lt;br /&gt;      count(distinct employee_id) current_employee_count &lt;br /&gt;      from #employment &lt;br /&gt;      where start_date &amp;lt;= getdate() &lt;br /&gt;        and (end_date &amp;gt; getdate() &lt;br /&gt;             or &lt;br /&gt;             end_date is null&lt;br /&gt;            )&lt;br /&gt;      group by employer_id&lt;br /&gt;     ) hcc&lt;br /&gt;    on #employers.employer_id = hcc.employer_id&lt;br /&gt;&lt;br /&gt;go&lt;br /&gt;select * from #Employers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The last method that we will use is also a JOIN to a derived table, but in this case, we will use a single table to return both values.&amp;nbsp; Again, you will see that the results of the select statement are identical to the first&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;update #employers&lt;br /&gt;set   history_employee_count = null&lt;br /&gt;     ,current_employee_count = null&lt;br /&gt;go&lt;br /&gt;update #employers&lt;br /&gt;set   history_employee_count = isnull(hec.history_employee_count,0)&lt;br /&gt;     ,current_employee_count = isnull(hec.current_employee_count,0)&lt;br /&gt;from #employers&lt;br /&gt;  left join &lt;br /&gt;     (select employer_id&lt;br /&gt;          ,count(distinct employee_id) history_employee_count &lt;br /&gt;          ,sum(case when getdate() &amp;gt;= start_date &lt;br /&gt;                         and (getdate() &amp;lt; end_date or end_date is null) &lt;br /&gt;                         then 1 &lt;br /&gt;                    else 0 &lt;br /&gt;               end) current_employee_count&lt;br /&gt;      from #employment &lt;br /&gt;      group by employer_id&lt;br /&gt;     ) hec&lt;br /&gt;    on #employers.employer_id = hec.employer_id&lt;br /&gt;go&lt;br /&gt;select * from #Employers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Finally, this will clean up the temporary tables used in this article.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;drop table #Employers&lt;br /&gt;drop table #Employees&lt;br /&gt;drop table #Employment&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What this shows is that there is more than one way to do a lot of common tasks.&amp;nbsp; There isn&amp;#39;t always a right way, because often times several methods will achieve the same result.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To download the entire SQL script used in this post, click &lt;a title="SQL" href="http://sqlservernation.com/media/p/148.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=143" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Intermediate+SQL/default.aspx">Intermediate SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/UPDATE/default.aspx">UPDATE</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/JOIN/default.aspx">JOIN</category></item><item><title>Hashing large data strings with a User Defined Function</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/15/hashing-large-data-strings.aspx</link><pubDate>Mon, 16 Mar 2009 01:53:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:119</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=119</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/15/hashing-large-data-strings.aspx#comments</comments><description>&lt;p&gt;If you have ever tryed to hash data in SQL Server using SQL Server&amp;#39;s build in &lt;a title="HASHBYTES" href="http://msdn.microsoft.com/en-us/library/ms174415.aspx"&gt;HASHBYTES&lt;/a&gt;, you know that that it doesn&amp;#39;t accept greater than 8000 bytes of data.&amp;nbsp; While that may work for a lot of scenarios, it doesn&amp;#39;t help when you have large strings.&amp;nbsp; Below we will go over the basics of a function that I use for HASHING large data strings.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The basic way that this function works is that it takes the input @String which is nvarchar(max), splits it into 8000 byte (4000 character) chunks and hashes them.&amp;nbsp; Each 8000 byte chunk is hashed using SQL Server&amp;#39;s built in HASHBYTES function.&amp;nbsp; The result is then converted into a char(32) string using sys.fn_varbintohexstr so that they may be concatenated.&amp;nbsp; Since each 4000 characters turns into a 32 character HASH, strings up to 1,000,000 characters will be hashed without having to make a recursive call.&amp;nbsp; While the below function utilizes a CROSS JOINED common table expression to generate the numbers it will need, the optimal way to achieve this would be to use a numbers table.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function dbo.fn_hashbytesMAX&lt;br /&gt;     (@string nvarchar(max)&lt;br /&gt;     ,@Algo    varchar(10)&lt;br /&gt;    )&lt;br /&gt;    returns binary(16)&lt;br /&gt;as&lt;br /&gt;/************************************************************&lt;br /&gt;*&lt;br /&gt;*    Author:        Brandon Galderisi&lt;br /&gt;*    Last modified: 03-MAR-2009&lt;br /&gt;*    Purpose:       uses the system function hashbytes as well&lt;br /&gt;*                   as sys.fn_varbintohexstr to split an &lt;br /&gt;*                   nvarchar(max) string and hash in 8000 byte &lt;br /&gt;*                   chunks hashing each 8000 byte chunk,,&lt;br /&gt;*                   getting the 32 byte output, streaming each &lt;br /&gt;*                   32 byte output into a string then hashing &lt;br /&gt;*                   that string.&lt;br /&gt;*&lt;br /&gt;*************************************************************/&lt;br /&gt;begin&lt;br /&gt;     declare    @concat       varchar(max)&lt;br /&gt;               ,@concatX      XML&lt;br /&gt;               ,@NumHash      int&lt;br /&gt;               ,@HASH         binary(16)&lt;br /&gt;     set @NumHash = ceiling((datalength(@string)/2)/(4000.0))&lt;br /&gt;    /* HashBytes only supports 8000 bytes so split the string if it is larger */&lt;br /&gt;    if @NumHash&amp;gt;1&lt;br /&gt;    begin&lt;br /&gt;                                                        -- # * 4000 character strings&lt;br /&gt;          ;with a as (select 1 as n union all select 1) -- 2 &lt;br /&gt;               ,b as (select 1 as n from a ,a a1)       -- 4&lt;br /&gt;               ,c as (select 1 as n from b ,b b1)       -- 16&lt;br /&gt;               ,d as (select 1 as n from c ,c c1)       -- 256&lt;br /&gt;               ,e as (select 1 as n from d ,d d1)       -- 65,536&lt;br /&gt;               ,f as (select 1 as n from e ,e e1)       -- 4,294,967,296 = 17+ TRILLION characters&lt;br /&gt;               ,factored as (select row_number() over (order by n) rn from f)&lt;br /&gt;               ,factors as (select rn,(rn*4000)+1 factor from factored)&lt;br /&gt;&lt;br /&gt;          select @concat = cast((&lt;br /&gt;          select right(sys.fn_varbintohexstr&lt;br /&gt;                         (&lt;br /&gt;                         hashbytes(@Algo, substring(@string, factor - 4000, 4000))&lt;br /&gt;                         )&lt;br /&gt;                      , 32) + &amp;#39;&amp;#39;&lt;br /&gt;          from Factors&lt;br /&gt;          where rn &amp;lt;= @NumHash&lt;br /&gt;          for xml path(&amp;#39;&amp;#39;)&lt;br /&gt;          ) as nvarchar(max))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;          set @HASH = dbo.fn_hashbytesMAX(@concat ,@Algo)&lt;br /&gt;    end&lt;br /&gt;     else&lt;br /&gt;     begin&lt;br /&gt;          set @HASH = convert(binary(16), hashbytes(@Algo, @string))&lt;br /&gt;     end&lt;br /&gt;&lt;br /&gt;return @HASH&lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The below sample script will take a 100 character base string and expand it&amp;#39;s size by concatenating the reverse of itself as it loops 16 times.&amp;nbsp; The result is a 3,276,800 character string which is then hashed using the fn_HASHBYTESMAX user defined function&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;&lt;br /&gt;declare    @nv      nvarchar(max)&lt;br /&gt;          ,@i       int&lt;br /&gt;          ,@dt      datetime&lt;br /&gt;set @i=1&lt;br /&gt;set @NV=N&amp;#39;012345789a!@#$%^&amp;amp;*()!@#$%^&amp;amp;*()9abcdeghijkl!@#$%^&amp;amp;*()mno012345689abcde2356!@#$%^&amp;amp;*()789abcdefgijklmno&amp;#39;&lt;br /&gt;while @i&amp;lt;16&lt;br /&gt;     select @NV=@NV+reverse(@NV),@i=@i+1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;set @dt=getdate()&lt;br /&gt;select  dbo.fn_hashbytesMAX(@nv,&amp;#39;MD5&amp;#39;)&lt;br /&gt;select datediff(ms,@dt,getdate()) as &amp;#39;Hash Time (ms)&amp;#39;,datalength(@nv)/2 as &amp;#39;String Character Length&amp;#39;&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The above query will generate two results.&amp;nbsp; The first is the BINARY(16) output of the function.&amp;nbsp; The second is the time (in ms) that it took to hash the string and the size of the string.&amp;nbsp; The machine that this was tested on is no powerhouse by today&amp;#39;s standard, but you will see that it was able to hash a 3M+ character string in just 273ms.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Hashing+large+data+strings+with+a+User+Defined+Function/res_5F00_HASH.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Hashing+large+data+strings+with+a+User+Defined+Function/res_5F00_HASH.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Hashing+large+data+strings+with+a+User+Defined+Function/res_5F00_time_5F00_len.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Hashing+large+data+strings+with+a+User+Defined+Function/res_5F00_time_5F00_len.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope that you find this function useful.&amp;nbsp; In the future we will be making use of this function to allow fast, INDEX searching of large fields.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=119" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/sql+2005/default.aspx">sql 2005</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Advanced+SQL/default.aspx">Advanced SQL</category></item><item><title>User Defined Functions</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/user-defined-functions.aspx</link><pubDate>Sat, 07 Mar 2009 17:50:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:83</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=83</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/user-defined-functions.aspx#comments</comments><description>&lt;p&gt;User defined functions have many uses in SQL Server.&amp;nbsp; Functions are useful to help clean up complex string manipulation logic in other areas of code and many other things.&amp;nbsp; But convenience is not free.&amp;nbsp; There is overhead in using functions and we will go over that later in the article.&lt;/p&gt;
&lt;p&gt;There are two types of User Defined Functions in SQL Server, Scalar Valued and Table Valued Functions.&amp;nbsp; Scalar Valued functions are used to return a single value whereas Table Valued functions return a table.&amp;nbsp; The table can be one or more columns and one or more rows.&amp;nbsp; While the structure for creating each type of function is nearly identical, how you use them is different.&lt;/p&gt;
&lt;p&gt;First let&amp;#39;s create a basic Scalar Valued function to show the proper way to construct your function.&amp;nbsp; For Scalar Valued Functions, you start with the keywords &amp;quot;create function&amp;quot;.&amp;nbsp; The next thing is the name of the function.&amp;nbsp; While it is not necessary to provide the schema name when naming the function, you will need to provide the schema name when using the function.&amp;nbsp; The next thing you provide is the keyword &amp;quot;returns&amp;quot; followed by the data type to be returned.&amp;nbsp; Returns says &amp;quot;This is the type of value that the function will return.&amp;nbsp; The next thing is the keyword &amp;quot;as&amp;quot;.&amp;nbsp; Like in stored procedures, it separates the definition of the function from the code of the function.&amp;nbsp; The next thing to know is that the code in a function MUST be contained within a BEGIN/END block.&amp;nbsp; And the last thing to know is that the last thing that a function must do is RETURN the value.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This basic function uses the dateadd and datediff functions to strip the time portion of the @DateTime parameter to have it return the DATE at midnight.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function dbo.fn_GetDateOnly(@DateTime datetime)&lt;br /&gt;returns datetime&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;return dateadd(d, datediff(d, 0, @DateTime), 0)&lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now how do we use scalar valued functions?&amp;nbsp; You use the function by selecting it.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;select dbo.fn_GetDateOnly(getdate())&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The result will be the the date which you run it with the time of midnight.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_GetDateOnly.png"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_GetDateOnly.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can also use it to format a datetime column as you select it from your table.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;select dbo.fn_GetDateOnly(SomeDateField) as SomeDate&lt;br /&gt;from SomeTable&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next we will create a simple Table Valued Function.&amp;nbsp; This function accepts a datetime parameter and then inserts the date of, before and after into the table for the function.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function dbo.fn_DatesTable(@BaseDate datetime)&lt;br /&gt;returns @Dates table (theDate datetime)&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;insert into @Dates (Thedate)&lt;br /&gt;values(Dateadd(d, datediff(d, 0, @BaseDate)-1, 0))&lt;br /&gt;insert into @Dates (Thedate)&lt;br /&gt;values(Dateadd(d, datediff(d, 0, @BaseDate), 0))&lt;br /&gt;insert into @Dates (Thedate)&lt;br /&gt;values(Dateadd(d, datediff(d, 0, @BaseDate)+1, 0))&lt;br /&gt;return&lt;br /&gt;end&lt;br /&gt;GO&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The below SQL shows you the difference in calling a Table Valued function as opposed to Scalar Valued functions.&amp;nbsp; You don&amp;#39;t select it, you select from it.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;select * from dbo.fn_datestable(&amp;#39;2009-03-07 12:00 pm&amp;#39;)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The results will be:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_GetDateOnly.png"&gt;&lt;/a&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_DatesTable.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_DatesTable.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Another, less commonly used syntax for creating a table valued function is below.&amp;nbsp; This syntax is useful when you are using a user defined function in place of a view because you need to specify parameters.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function dbo.fn_dosomething()&lt;br /&gt;returns  TABLE&lt;br /&gt;as&lt;br /&gt;&lt;br /&gt;return &lt;br /&gt;(         select cast(1 as int) as Id, cast(N&amp;#39;Hello&amp;#39; as nvarchar(50)) as theValue&lt;br /&gt;union all select 2,&amp;#39;Good Bye&amp;#39;&lt;br /&gt;)&lt;br /&gt;GO&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now comes the bad news.&amp;nbsp; While functions are useful tools, they are not for every scenario.&amp;nbsp; There is some overhead to using functions.&amp;nbsp; The below Test script will loop 100,000 times and assign the function&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;declare &lt;br /&gt;      @SampleDate   datetime&lt;br /&gt;     ,@dt           datetime&lt;br /&gt;     ,@dt2          datetime&lt;br /&gt;     ,@i            int&lt;br /&gt;declare @res table&lt;br /&gt;     (Method        varchar(20)&lt;br /&gt;     ,Time_In_Ms    int&lt;br /&gt;     )&lt;br /&gt;set @SampleDate = getdate()&lt;br /&gt;set @dt = getdate()&lt;br /&gt;set @i=1&lt;br /&gt;while @i&amp;lt;100000&lt;br /&gt;begin&lt;br /&gt;     set @dt2=dbo.fn_GetDateOnly(@sampleDate+@i)&lt;br /&gt;set @i=@i+1&lt;br /&gt;end&lt;br /&gt;insert into @Res(Method,time_In_Ms)&lt;br /&gt;values(&amp;#39;Function&amp;#39;, datediff(ms, @dt, getdate()))&lt;br /&gt;&lt;br /&gt;set @dt = getdate()&lt;br /&gt;set @i=1&lt;br /&gt;while @i&amp;lt;100000&lt;br /&gt;begin&lt;br /&gt;     set @dt2=dateadd(d, datediff(d, 0, @SampleDate+@i), 0)&lt;br /&gt;set @i=@i+1&lt;br /&gt;end&lt;br /&gt;insert into @Res(Method,time_In_Ms)&lt;br /&gt;values(&amp;#39;SQL&amp;#39;, datediff(ms, @dt, getdate()))&lt;br /&gt;select * from @Res&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see by this output, executing the same statement through a function is slower than using an inline SQL.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_VS_5F00_inline.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.User+Defined+Functions/res_5F00_fn_5F00_VS_5F00_inline.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now that you know the basics of functions, you are ready to get into some tougher examples.&amp;nbsp; Look for more postings specific on scalar and table valued functions.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=83" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/table+valued+function/default.aspx">table valued function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/scalar+valued+function/default.aspx">scalar valued function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category></item><item><title>Table Valued Functions</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/table-valued-functions.aspx</link><pubDate>Sat, 07 Mar 2009 17:33:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:81</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=81</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/table-valued-functions.aspx#comments</comments><description>&lt;p&gt;A table valued function is a function that returns a table instead of a single value.&amp;nbsp; In this post, we will go over the Table Valued Functions in more detail than we did in the general topic covering &lt;a title="User Defined Functions" href="http://sqlservernation.com/blogs/howtos/archive/2009/03/07/user-defined-functions.aspx"&gt;User Defined Functions&lt;/a&gt;.&amp;nbsp; There are many uses for table valued functions so we will go over a couple of examples to ensure that you will be successful when you begin to create your own.&lt;/p&gt;
&lt;p&gt;The first thing you need to understand is how you define a function as a Table Valued Function.&amp;nbsp; This is done by defining a table variable as the type of value returned.&amp;nbsp; The syntax for declaring the output table variable is similar to how you would declare a table variable in a stored procedure with the exception that instead of using the DECLARE keyword, you use RETURNS. The next thing, like every other function, is that you must have&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the below example we do a simple insert of two values into the table and returns.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function dbo.fn_dosomething()&lt;br /&gt;returns @A_Table TABLE&lt;br /&gt;     (ident    int identity primary key clustered&lt;br /&gt;     ,theValue nvarchar(50)&lt;br /&gt;     )&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;insert into @A_Table(theValue) values(&amp;#39;Hello&amp;#39;)&lt;br /&gt;&lt;/code&gt;&lt;code&gt;insert into @A_Table(theValue) values(&amp;#39;Good Bye&amp;#39;)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;return&lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The below example is made to take a string containing a name and
divide it into the first and last name.&amp;nbsp; The below function will take a
single input parameter and divide it into first and last name.&amp;nbsp; This
would be useful if, due to poor design decisions, the user table
contained a single field for name instead of first and last names.&amp;nbsp;
Since the name field is a single field, you have no control over what
format people entered their data in.&amp;nbsp; They could have done &amp;quot;Last Name,
First Name&amp;quot;, &amp;quot;First Name Last Name&amp;quot; or simply &amp;quot;First Name&amp;quot;.&amp;nbsp; This
function implements business logic to determine how the various values
should be parsed.
&lt;/p&gt;
&lt;p&gt;The Function:&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function dbo.fn_SplitName(@Name varchar(100))&lt;br /&gt;returns @Names table (FirstName varchar(100), LastName varchar(100))&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;if datalength(@Name)&amp;gt;0&lt;br /&gt;begin&lt;br /&gt;     if charindex(&amp;#39;,&amp;#39;,@name)&amp;gt;0           -- Supports &amp;quot;Lastname, Firstname&amp;quot; Format&lt;br /&gt;          insert into @Names (LastName, FirstName)&lt;br /&gt;          select left(@Name, charindex(&amp;#39;,&amp;#39;,@Name)-1), &lt;br /&gt;                      ltrim(rtrim(right(@Name, charindex(&amp;#39;,&amp;#39;, reverse(@Name))-1)))&lt;br /&gt;     else if charindex(&amp;#39; &amp;#39;, @Name)&amp;gt;0     -- Supports &amp;quot;Firstname LastName&amp;quot; Format&lt;br /&gt;          insert into @Names (LastName, FirstName)&lt;br /&gt;          select ltrim(rtrim(right(@Name, charindex(&amp;#39; &amp;#39;, reverse(@Name))-1))), &lt;br /&gt;                      left(@Name, charindex(&amp;#39; &amp;#39;,@Name)-1)&lt;br /&gt;     else                                -- If no match above, return as first name.&lt;br /&gt;          insert into @Names (FirstName)&lt;br /&gt;          values(@Name)&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;return&lt;br /&gt;end&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
This function searches for certain characters within the passed variable.&amp;nbsp; It is not intended to be a useful function for parsing ALL formats of names, those have to be defined by your organization or needs.&amp;nbsp; If you have the need for a specific User Defined Function, please post it in our &lt;a title="SQL Help Forums" href="http://sqlservernation.com/forums/default.aspx?GroupID=7"&gt;SQL Help Forums&lt;/a&gt; and someone will help you out as soon as possible.&lt;/p&gt;
&lt;p&gt;Table Valued Functions are useful in the place of views where you need to define parameters for what data is selected.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=81" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/table+valued+function/default.aspx">table valued function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category></item><item><title>A View of Numbers</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/a-view-of-nmbers.aspx</link><pubDate>Sat, 07 Mar 2009 05:35:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:77</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=77</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/a-view-of-nmbers.aspx#comments</comments><description>&lt;p&gt;The below view will generate a list of numbers ranging from 1 - 4,294,967,296.&amp;nbsp; This view can be used in place of a physical table of numbers for some small operations but since it utilizes several large cross joins it is not very efficient once it starts counting into large numbers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create view vw_Nums&lt;br /&gt;as&lt;br /&gt;with   cte0 as (select 1 as c union all select 1), &lt;br /&gt;       cte1 as (select 1 as c from cte0 a, cte0 b), &lt;br /&gt;       cte2 as (select 1 as c from cte1 a, cte1 b), &lt;br /&gt;       cte3 as (select 1 as c from cte2 a, cte2 b), &lt;br /&gt;       cte4 as (select 1 as c from cte3 a, cte3 b), &lt;br /&gt;       cte5 as (select 1 as c from cte4 a, cte4 b), &lt;br /&gt;       nums as (select row_number() over (order by c) as n from cte5)&lt;br /&gt;       select n from nums &lt;br /&gt;go&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This view will be referenced for use in the user defined functions that we publish in case you don&amp;#39;t have a numbers table&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=77" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/view/default.aspx">view</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/function/default.aspx">function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/numbers+table/default.aspx">numbers table</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/sql+2005/default.aspx">sql 2005</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category></item><item><title>Converting a delimited string into a table</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/converting-a-delimited-string-into-a-table.aspx</link><pubDate>Sat, 07 Mar 2009 05:25:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:76</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=76</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/07/converting-a-delimited-string-into-a-table.aspx#comments</comments><description>&lt;p&gt;In this article, I will show you how you can convert a delimited string of data into a table of data.&amp;nbsp; In order to do this we will use a table valued function.&amp;nbsp; There are many ways to achieve this but this how I like to do it.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;In order to use the function, you will need a numbers table.&amp;nbsp; Since that&amp;#39;s a topic that we haven&amp;#39;t covered here yet, we will utilize a view that builds one on the fly.&amp;nbsp; The view can be found in the &lt;a title="A View of Numbers" href="http://sqlservernation.com/blogs/howtos/archive/2009/03/07/a-view-of-nmbers.aspx"&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a title="A View of Numbers" href="http://sqlservernation.com/blogs/howtos/archive/2009/03/07/a-view-of-nmbers.aspx"&gt;A View of Numbers&lt;/a&gt; post.&amp;nbsp; If you have a numbers table, replace &amp;quot;vw_nums&amp;quot; with the name of the table in the below function and replace &amp;quot;n&amp;quot; with the column name that contains your numbers.&lt;/p&gt;
&lt;p&gt;Run the following SQL to create the function.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;create function [dbo].[fn_DelimitedToTable](@DelimitedString nvarchar(max), @Delimiter nvarchar(32))&lt;br /&gt;returns @Values TABLE&lt;br /&gt;     (ident         int not null identity primary key clustered&lt;br /&gt;     ,thePosition   int not null&lt;br /&gt;     ,theValue      nvarchar(max)&lt;br /&gt;     )&lt;br /&gt;as&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;insert into @Values (thePosition,theValue)&lt;br /&gt;select n&lt;br /&gt;  ,substring(@delimiter + @DelimitedString + @delimiter&lt;br /&gt;            ,n + (datalength(@delimiter)/2)&lt;br /&gt;            ,charindex(@delimiter, @delimiter + @DelimitedString + @delimiter&lt;br /&gt;                      ,n + datalength(@delimiter)/2) - n - datalength(@delimiter)/2&lt;br /&gt;                      ) as string_value&lt;br /&gt;from    dbo.vw_Nums&lt;br /&gt;where&lt;br /&gt;    n &amp;lt;= (datalength(@delimiter + @DelimitedString + @delimiter)/2) - (datalength(@delimiter)/2)&lt;br /&gt;and substring(@delimiter + @DelimitedString + @delimiter, n, (datalength(@delimiter)/2)) = @delimiter&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;return&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This function works by utilizing the numbers table to represent the characters in the string.&amp;nbsp; This allows SQL Server to quickly find the @Delimiter in the string without doing any sort of while loops or cursors.&amp;nbsp; It accepts a @DelimitedString and a @delimiter as input, and outputs three values.&amp;nbsp; The @DelimitedString input parameter is a nvarchar(max) input parameter, but the actual string to be parsed can be no longer than the number of values in your numbers table.The &amp;quot;ident&amp;quot; field is an identity field that represents the position of the parsed string within the @DelimitedString.&amp;nbsp; The field &amp;quot;thePosition&amp;quot; represents the starting position of the value within the @DelimitedString.&amp;nbsp; The field &amp;quot;theValue&amp;quot; is the value within the @DelimitedString that falls between two instances of the @Delimiter.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;This will show you the basics of how this function works and what you can expect to see.&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;select * from [dbo].[fn_DelimitedToTable](&amp;#39;Jim,John,Mike,Bob,Tom&amp;#39;,&amp;#39;,&amp;#39;)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Delimited+to+Table/res_5F00_5_5F00_names.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Delimited+to+Table/res_5F00_5_5F00_names.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, it returns the five names in the string, in the order they appeared.&amp;nbsp; This script is useful when an application has to pass in a delimited
list of values to search for.&amp;nbsp; By splitting the values into a table it
can be joined to for selecting multiple values.&lt;/p&gt;
&lt;p&gt;This example shows that you can use a delimiter greater than one character.&amp;nbsp; This is useful when your data can contain any character and there is no ONE character that you can use to delimit the string.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;select * from [dbo].[fn_DelimitedToTable](&amp;#39;a|%25basdf|%25c|%25d&amp;#39;,&amp;#39;|%25&amp;#39;)&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;span style="text-decoration:underline;"&gt;&lt;b&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Delimited+to+Table/res_5F00_4_5F00_multi_5F00_delmited.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Delimited+to+Table/res_5F00_4_5F00_multi_5F00_delmited.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s talk about some possible uses for this type of functionality.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Let&amp;#39;s say that your application needs to search and return a list of employees.&amp;nbsp; There are many ways to pass in the parameters.&amp;nbsp; One of which is XML.&amp;nbsp; But SQL Server isn&amp;#39;t the most efficient as processing XML so for this case we will use a delimited string.&amp;nbsp; The first thing we need to do is setup our test table &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: If the table name looks strange, I use a partial newid() value to make the table unique.&amp;nbsp; Although we recommend that you never test on a production server, or even in a used database on a development server, we try to make the names unique to prevent conflicting with your existing tables.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;create table dbo.employees_FB8AD58DADAF&lt;br /&gt;     (userid        int identity primary key clustered&lt;br /&gt;     ,firstname     nvarchar(50) not null&lt;br /&gt;     ,lastname      nvarchar(50) not null&lt;br /&gt;     )&lt;br /&gt;GO&lt;br /&gt;insert into dbo.employees_FB8AD58DADAF(firstname,lastname)&lt;br /&gt;          select &amp;#39;Jim&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;John&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;Mike&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;Bob&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;Tom&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;Tim&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;Rob&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;union all select &amp;#39;Matt&amp;#39;, &amp;#39;Smith&amp;#39;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s see how we can use the above function to search.&amp;nbsp; The below procedure accepts a @userlist parameter.&amp;nbsp; The @userlist parameter is a comma delimited list of user first names to search for in the table we created.&amp;nbsp; When we create and run the below procedure&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;create procedure dbo.up_employeesearch&lt;br /&gt;      @UserList   nvarchar(max)&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;select e.userid,e.firstname,e.lastname from dbo.employees_FB8AD58DADAF e&lt;br /&gt;  join [dbo].[fn_DelimitedToTable](@userlist,N&amp;#39;,&amp;#39;) t&lt;br /&gt;    on e.firstname = t.thevalue&lt;br /&gt;go&lt;br /&gt;exec dbo.up_employeesearch @userlist = &amp;#39;Jim,John,Mike,Bob,Tom&amp;#39;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We get the following results:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Delimited+to+Table/res_5F00_5_5F00_searched.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Delimited+to+Table/res_5F00_5_5F00_searched.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There are a lot of uses for this type of functionality and I&amp;#39;m sure you can already think of a few.&amp;nbsp; Just remember that before you start making too much use of this, you should consider converting it to use a numbers table instead of the vw_nums view.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=76" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Intermediate+SQL/default.aspx">Intermediate SQL</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/function/default.aspx">function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/numbers+table/default.aspx">numbers table</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/table+valued+function/default.aspx">table valued function</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/numbers/default.aspx">numbers</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/User+Defined+Functions/default.aspx">User Defined Functions</category></item><item><title>Stored Procedures</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/06/stored-procedures.aspx</link><pubDate>Fri, 06 Mar 2009 23:54:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:73</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=73</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/06/stored-procedures.aspx#comments</comments><description>&lt;p&gt;Stored procedures are part of the core functionality of a DBMS.&amp;nbsp; SQL Server is no exception to that.&amp;nbsp; Stored procedures have many uses.&amp;nbsp; They can be used to handle basic CRUD operations as well as complex logic.&amp;nbsp; There are several things that you have to consider when it comes to building stored procedures for you database.&amp;nbsp; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is this something that has to be done in the database?&lt;/li&gt;
&lt;li&gt;Is this something that should be done in the database?&lt;/li&gt;
&lt;li&gt;Does my database server have the capacity to handle this as it&amp;#39;s use scales.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Above there are three questions you need to ask yourself but they are not the only three.&amp;nbsp; Since there is no way for us to answer any of these questions, we&amp;#39;ll talk briefly about it and concentrate on the what you can do and how.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Is this something that has to be done in the database?&lt;br /&gt;&lt;/b&gt;There are benefits to keeping your logic contained in the database.&amp;nbsp; It&amp;#39;s easy to patch by installing new procedures or updating existing ones.&amp;nbsp; All of the logic is contained inside of one location instead of being spread out in embedded SQL in applications.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Is this something that should be done in the database?&lt;br /&gt;&lt;/b&gt;SQL Server&amp;#39;s primary purpose is to store your information.&amp;nbsp; And it&amp;#39;s great at a lot of things, and not at others.&amp;nbsp; The more work that is done in the database, the higher the load placed on the database server.&amp;nbsp; This can lead to a lot of issues including increased CPU and memory usage which can take away from SQL Server&amp;#39;s ability to do what it HAS to do.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Does my database server have the capacity to handle this as it&amp;#39;s use scales?&lt;br /&gt;&lt;/b&gt;I can&amp;#39;t tell you how many times I&amp;#39;ve heard people say &amp;quot;there will only be 10 users&amp;quot; or &amp;quot;there will never be more than a few hundred records&amp;quot;.&amp;nbsp; If you write inefficient SQL because you expect small usage, then by habit you will write inefficient SQL for large scale operations.&amp;nbsp; I&amp;#39;m not saying to over-engineer every table.&amp;nbsp; Sometimes it is OK to bend the rules a little.&amp;nbsp; But it has to be a clear and conscious decision to do such&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now on to &lt;b&gt;Stored Procedures&lt;/b&gt;.&amp;nbsp; I will first start by showing a very simple stored procedure that shows the structure, then we&amp;#39;ll discuss it&amp;#39;s structure.&amp;nbsp; There are are lot of different things to know, even about the basics of stored procedures.&amp;nbsp; So this will be a rather long posting.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectHello&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;select &amp;#39;Hello&amp;#39;&lt;br /&gt;return&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Above is a very basic, and impractical, procedure that does nothing other than select the word &amp;#39;Hello&amp;#39;.&amp;nbsp; To create a stored procedure, you start off by saying &amp;quot;CREATE PROCEDURE&amp;quot;.&amp;nbsp; The next thing that you do is give the name.&amp;nbsp; You do not have to specify the schema, but it&amp;#39;s a good idea to do so.&amp;nbsp; Above, I have selected the dbo schema.&amp;nbsp; The next thing after the name is the keyword &amp;quot;as&amp;quot;.&amp;nbsp; As has many uses in SQL Server.&amp;nbsp; In stored procedures, it is used to separate the definition of the stored procedure from the code of the stored procedure.&amp;nbsp; The next line, &amp;quot;set nocount on&amp;quot; is not specific to stored procedures, but it will prevent the stored procedure from outputing the number of rows effected by various operations in the query.&amp;nbsp; Next is the simple select statement followed by return.&amp;nbsp; Return is not required in stored procedures.&amp;nbsp; But when a return is executed, the procedure exits immediately.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;EXEC dbo.up_SelectHello&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Calling the procedure from within SQL Server Management Studio is as simple as running the above command in a query window.&amp;nbsp; An important thing to note is that if you are only executing one command in a batch, you do not need to include the EXEC.&amp;nbsp; So the below statements are all valid was to call the procedure.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;EXEC dbo.up_SelectHello&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;dbo.up_SelectHello&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;dbo.up_SelectHello&lt;br /&gt;go&lt;br /&gt;select &amp;#39;Something Else&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This last is valid because the GO separates the first and second statement into two different batches.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @Input nvarchar(100)&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;select @input&lt;br /&gt;return&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
The above goes one step further and uses an input parameter as the text to select.&amp;nbsp; While this procedure is equally useless, it shows the structure of allowing input parameters.&amp;nbsp; The structure is that you include the variable name and it&amp;#39;s data type between the procedure name and the &amp;quot;as&amp;quot; statement.&amp;nbsp; You can also provide multiple parameters by separating them by commas, as shown below.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @Input   nvarchar(100)&lt;br /&gt; ,@Input2  nvarchar(100)&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;select @input + @input2&lt;br /&gt;return&lt;br /&gt;go&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Going to the next level, you can provide default values for input parameters.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @Input nvarchar(100) = N&amp;#39;Hello&amp;#39;&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;select @input&lt;br /&gt;return&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What this does is allow the parameter to have a value if the parameter is not specified in the execution call.&amp;nbsp; This does not mean that if you specify NULL that it will use the value&amp;nbsp; So if the following 3 procedure calls are made:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;EXEC dbo.up_SelectInput @input=N&amp;#39;Hello&amp;#39;&lt;br /&gt;EXEC dbo.up_SelectInput &lt;br /&gt;EXEC dbo.up_SelectInput NULL&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The results in order will be:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_hello.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_hello.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_hello.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_hello.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_NULL.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_NULL.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that for the last call, I did not specify @input in the EXEC statement.&amp;nbsp; SQL Server does not require you to specify the parameter name when passing them to a procedure call.&amp;nbsp; Instead, it will accept the parameters in the order in which they are provided.&amp;nbsp; But if you specify the name for a parameter, you must specify the name for all subsequent parameters.&lt;/p&gt;
&lt;p&gt;So with the following procedure:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @Input   nvarchar(100) = N&amp;#39;hello&amp;#39;&lt;br /&gt; ,@Input2  nvarchar(100) = N&amp;#39;goodbye&amp;#39;&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;select @input + N&amp;#39; &amp;#39; + @input2&lt;br /&gt;return&lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;You will get the following results with these commands:&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;exec dbo.up_SelectInput @input=N&amp;#39;SQL Server&amp;#39; ,@input2=N&amp;#39;Nation&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_SSN.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_SSN.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;exec dbo.up_SelectInput N&amp;#39;SQL Server&amp;#39;,@input2=N&amp;#39;Nation&amp;#39;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_SSN.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_SSN.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;exec dbo.up_SelectInput @input=N&amp;#39;SQL Server&amp;#39;, N&amp;#39;nation&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style="color:red;"&gt;Msg 119, Level 15, State 1, Line 1&lt;br /&gt;Must pass parameter number 2 and subsequent parameters as &amp;#39;@name = value&amp;#39;. After the form &amp;#39;@name = value&amp;#39; has been used, all subsequent parameters must be passed in the form &amp;#39;@name = value&amp;#39;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Output parameters allow you to get data OUT of a stored procedure.&amp;nbsp; In order to specify a parameter as an OUTPUT parameter, you add the keyword OUTPUT after the data type definition.&amp;nbsp; This does not mean that you can not pass a value in if it is defined as output, but it allows you to pass a value out.&amp;nbsp; In the below procedure, you will see that we are concatenating the first two parameters and assigning it to the third parameter.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @param1  nvarchar(100) = N&amp;#39;hello&amp;#39;&lt;br /&gt; ,@param2  nvarchar(100) = N&amp;#39;goodbye&amp;#39;&lt;br /&gt; ,@param3  nvarchar(100) output&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;set @param3 = @&lt;/code&gt;&lt;code&gt;param1 &lt;/code&gt;&lt;code&gt;+ N&amp;#39; &amp;#39; + @&lt;/code&gt;&lt;code&gt;param2  &lt;/code&gt;&lt;br /&gt;&lt;code&gt;return&lt;br /&gt;go&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now to get the value from the parameter, it is a little different.&amp;nbsp; Since executing the procedure will not select any data, we have to retrieve the value using a parameter.&amp;nbsp; Below we will pass in the parameter @output to accept the value of @param3.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;declare @output nvarchar(100)&lt;br /&gt;exec dbo.up_SelectInput @param1 = N&amp;#39;SQL Server&amp;#39;, @param2 = &amp;#39;Nation&amp;#39;, @param3 = @output output&lt;br /&gt;select @output&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Selecting @output you will see the the following result.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_SSN.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_SSN.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The last thing that I want to cover in this is the difference between return codes and output parameters.&amp;nbsp; The return code is the status of the procedure.&amp;nbsp; It is the value that is returned by the RETURN statement in the procedure.&amp;nbsp; By default, if you do not specify a value in the RETURN statement, the default of 0 is used.&amp;nbsp; You can only return an INTEGER from a procedure.&amp;nbsp; You can not return dates, or any other data types.&amp;nbsp; Only integers.&amp;nbsp; The default return code of 0 typically indicates that that the procedure executed successfully.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Let&amp;#39;s test using return codes.&amp;nbsp; We will start with the same basic procedure that we have been using.&amp;nbsp; and we will show how to call the procedure to capture the return code.&amp;nbsp;
Unlike output parameters, return codes are captured using the &amp;quot;exec
@parameter = procedure&amp;quot; syntax.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @param1  nvarchar(100) = N&amp;#39;hello&amp;#39;&lt;br /&gt; ,@param2  nvarchar(100) = N&amp;#39;goodbye&amp;#39;&lt;br /&gt; ,@param3  nvarchar(100) output&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;set @param3 = @param1 + N&amp;#39; &amp;#39; + @param2  &lt;br /&gt;return &lt;br /&gt;go&lt;br /&gt;&lt;/code&gt;&lt;code&gt;declare @output          nvarchar(100)&lt;br /&gt;       ,@ReturnCode      INT&lt;br /&gt;exec @ReturnCode = dbo.up_SelectInput @param1 = N&amp;#39;SQL Server&amp;#39;, @param2 = &amp;#39;Nation&amp;#39;, @param3 = @output output&lt;br /&gt;&lt;br /&gt;select @ReturnCode&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you will see, the value of @returncode is 0.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_0.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_0.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="border:1px dashed #999999;padding:5px;overflow:auto;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;color:#000000;background-color:#eeeeee;font-size:12px;line-height:14px;width:100%;"&gt;&lt;code&gt;CREATE PROCEDURE dbo.up_SelectInput&lt;br /&gt;  @param1  nvarchar(100) = N&amp;#39;hello&amp;#39;&lt;br /&gt; ,@param2  nvarchar(100) = N&amp;#39;goodbye&amp;#39;&lt;br /&gt; ,@param3  nvarchar(100) output&lt;br /&gt;as&lt;br /&gt;set nocount on&lt;br /&gt;set @param3 = @param1 + N&amp;#39; &amp;#39; + @param2  &lt;br /&gt;return 1&lt;br /&gt;go&lt;br /&gt;&lt;br /&gt;declare @output          nvarchar(100)&lt;br /&gt;       ,@ReturnCode      INT&lt;br /&gt;exec @ReturnCode = dbo.up_SelectInput @param1 = N&amp;#39;SQL Server&amp;#39;, @param2 = &amp;#39;Nation&amp;#39;, @param3 = @output output&lt;br /&gt;&lt;br /&gt;select @ReturnCode&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you will see, the value of @returncode is 1.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sqlservernation.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_1.PNG"&gt;&lt;img src="http://sqlservernation.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/howtos.Stored+Procedures/res_5F00_1.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Return codes are useful for passing information back about what happened in a procedure.&amp;nbsp; For example a user authentication procedure could be used to validate that a username and password hash passed in are valid for a particular user.&amp;nbsp; Using return codes you could differentiate between a successful authentication, a failed password match, an invalid username, or anything else you would desire.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope that you enjoyed this overview on the basic structure of stored procedures.&amp;nbsp; Understanding how to construct stored procedures is an essential skill that you will need if you want to become a SQL Server master.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=73" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/variable/default.aspx">variable</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/stored+procedures/default.aspx">stored procedures</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/return/default.aspx">return</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/parameter/default.aspx">parameter</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/beginner/default.aspx">beginner</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Beginner+SQL/default.aspx">Beginner SQL</category></item><item><title>Changing the display format of DATETIME values</title><link>http://sqlservernation.com/blogs/howtos/archive/2009/03/05/changing-the-display-format-of-datetime-values.aspx</link><pubDate>Fri, 06 Mar 2009 03:24:00 GMT</pubDate><guid isPermaLink="false">a3dbd76b-19b9-441f-b40a-d79e8f433d35:61</guid><dc:creator>BrandonGalderisi</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://sqlservernation.com/blogs/howtos/rsscomments.aspx?PostID=61</wfw:commentRss><comments>http://sqlservernation.com/blogs/howtos/archive/2009/03/05/changing-the-display-format-of-datetime-values.aspx#comments</comments><description>&lt;p&gt;Often times, people want to change the format of a datetime value
returned from SQL Server.&amp;nbsp; There are some things that you need to
consider before doing this.&amp;nbsp; The first thing that you need to be aware
of is that SQL Server stores &lt;span style="color:#0000ff;"&gt;DATETIME&lt;/span&gt; values in an 8 byte value in the database, not as a string.&amp;nbsp; So changing the display format will change your &lt;span style="color:#0000ff;"&gt;DATETIME&lt;/span&gt; into a &lt;span style="color:#0000ff;"&gt;VARCHAR&lt;/span&gt; The &lt;span style="background-color:#ffffff;color:#0000ff;"&gt;SMALLDATETIME&lt;/span&gt; datatype is stored in a 4 byte value.&amp;nbsp; SQL Server 2008 introduces several new date datatypes including &lt;span style="color:#0000ff;"&gt;DATETIME2&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;DATE&lt;/span&gt;, and &lt;span style="color:#0000ff;"&gt;TIME&lt;/span&gt;.&amp;nbsp; The &lt;span style="color:#0000ff;"&gt;DATE &lt;/span&gt;and &lt;span style="color:#0000ff;"&gt;TIME&lt;/span&gt; data types will solve a lot of headaches for a lot of people because often times when people want to convert a &lt;span style="color:#0000ff;"&gt;DATETIME&lt;/span&gt; value to a varchar, it is because they want to display only the date or time portions of the value.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;To
display a date in a different format other than the default, you will
need to know the format code for the date.&amp;nbsp; For a full list of format
codes, visit the &lt;a href="http://sqlservernation.com/media/g/informational/default.aspx"&gt;Informational Downloads&lt;/a&gt; section.&amp;nbsp; Below, we will show some of the
more popular formats.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;declare @Date datetime&lt;br /&gt;set @Date = cast(&amp;#39;2008-04-01 12:01:23.123&amp;#39; as datetime)&lt;/p&gt;
&lt;div&gt;
&lt;table class="zeroBorder" id="h7bx" border="1" cellpadding="3" cellspacing="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align:center;" width="15%"&gt;&lt;b&gt;Format Code&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;" width="25%"&gt;&lt;b&gt;Format&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;" width="35%"&gt;&lt;b&gt;SQL&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;" width="25%"&gt;&lt;b&gt;Output&lt;/b&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;1&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;MM/DD/YY&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(8), @date, 1)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;04/01/08&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;3&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;DD/MM/YY&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(8), @date, 3)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;01/04/08&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;7&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;MMM DD, YY&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(10), @date, 7)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;Apr 01, 08&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;9&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;MMM D YYYY H:MM:SS:nnnAP&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(varchar(32), @date, 9)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;Apr 1 2008 2:01:23:123PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;101&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;MM/DD/YYYY&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(10), @date, 101)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;04/01/2008 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;103&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;DD/MM/YYYY&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(8), @date, 103)&lt;/td&gt;
&lt;td style="text-align:center;"&gt;01/04/2008&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;107&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;MMM DD, YYYY&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(12), @date, 107)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;Apr 01, 2008 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;111&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;YYYY/MM/DD&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(10), @date, 111)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;2008/04/01 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align:center;"&gt;112&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;YYYYMMDD&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;select convert(char(8), @date, 112)&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align:center;"&gt;20080401 &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;You
will find the above codes useful if you are generating SQL Queries that
must display formatted data.&amp;nbsp; But it is always best to leave your
datetime values as &lt;span style="color:#0000ff;"&gt;DATETIME&lt;/span&gt; values and leave the formatting to your application where you can!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://sqlservernation.com/aggbug.aspx?PostID=61" width="1" height="1"&gt;</description><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/datetime/default.aspx">datetime</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/time/default.aspx">time</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/date/default.aspx">date</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/cast/default.aspx">cast</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/convert/default.aspx">convert</category><category domain="http://sqlservernation.com/blogs/howtos/archive/tags/Intermediate+SQL/default.aspx">Intermediate SQL</category></item></channel></rss>