<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Everything old is new again &#187; sql</title>
	<atom:link href="http://www.svendtofte.com/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.svendtofte.com</link>
	<description>rantings &#38; scraps on code and web development</description>
	<lastBuildDate>Thu, 27 Aug 2009 22:38:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SQL split function</title>
		<link>http://www.svendtofte.com/geek-angst/sql-split-function/</link>
		<comments>http://www.svendtofte.com/geek-angst/sql-split-function/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 08:08:55 +0000</pubDate>
		<dc:creator>Svend</dc:creator>
				<category><![CDATA[Geek angst]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sql server]]></category>

		<guid isPermaLink="false">http://www.svendtofte.com/?p=162</guid>
		<description><![CDATA[Every time I need to work with SQL, it never ceases to amaze. The language is simply such an abortion in terms of development enviroments and simple programmer usability. Naturally, alot of this stems from my inexperience with the language. Mostly this post is just my own personal gripes with about SQL.
So, at work I [...]]]></description>
			<content:encoded><![CDATA[<p>Every time I need to work with SQL, it never ceases to amaze. The language is simply such an abortion in terms of development enviroments and simple programmer usability. Naturally, alot of this stems from my inexperience with the language. Mostly this post is just my own personal gripes with about SQL.</p>
<p>So, at work I find that I need a function which takes a variable number of GUIDs, and presents me with a compounded status integer, pulling status indicators for each GUID, and producing a single status. Should be simple right?</p>
<p><span id="more-162"></span></p>
<p>First off, I need this to be a function, so I can use it in <code>SELECT</code> constructs for a view. Why SQL has these random limitations on what can appear where, I&#8217;ll never know, but there it is. Then, the wild notion that I could pass in a variable number of GUIDs is killed fairly off quickly as SQL doesn&#8217;t support <a href="http://en.wikipedia.org/wiki/Variadic_function">variadic functions</a>.</p>
<p>So ok, I need to pass in the GUIDs in a single data structure. Of course, I know right off the bat, that I can&#8217;t pass tables (&lt;sarcasm&gt;why would anyone wanna do that anyway?&lt;/sarcasm&gt;), so we&#8217;ll just pack a string with the GUIDs I need. I&#8217;ll live with <code>myFunction("guid1,guid2,guid3")</code>. So taking a look over the <a href="http://msdn.microsoft.com/en-us/library/ms186323(SQL.90).aspx">extremely rich string function library in SQL</a>, I notice there&#8217;s no split function. So I need to write that first.</p>
<h3>Writing an SQL string split function</h3>
<p>So let&#8217;s just lay it out there. In all it&#8217;s glory.</p>
<pre>CREATE FUNCTION dbo.Split (@String VARCHAR(500), @Delimeter CHAR(1))
RETURNS @Strings TABLE (String VARCHAR(500))
AS
BEGIN
    DECLARE @Position INT,
            @Next INT,
            @DelimeterWidth INT,
            @Substring VARCHAR(500)

    SET @Position = 1
    SET @Next = 1 -- set to 1, just to get past initial while cond
    SET @DelimeterWidth = LEN(@Delimeter)

    WHILE @Next > 0
    BEGIN
        SET @Next = CHARINDEX(@Delimeter, @String, @Position)
        IF (@Next-@Position) >= 1
        BEGIN
            SET @Substring = SUBSTRING(@String,
                                       @Position+1,
                                       @Next - @Position - @DelimeterWidth)
            INSERT INTO @Strings(String) VALUES(@Substring)
        END
        SET @Position = @Next
    END

    RETURN
END
</pre>
<p>You&#8217;ll notice this returns a table. This table is btw also the <em>only one</em> you have to work with, no creating temporary tables! For some reason, <a href="http://databases.aspfaq.com/database/should-i-use-a-temp-table-or-a-table-variable.html">you&#8217;re not allowed to create tables inside functions</a>. So once you&#8217;re past the 1-indexed strings, you&#8217;re almost there . I know that 0 versus 1 indexing is <a href="http://c2.com/cgi/wiki?WhyNumberingShouldStartAtZero">a religious war onto itself</a>, but given <a href="http://en.wikipedia.org/wiki/Ordinal_number">Cantor&#8217;s ordinals</a> start at 0, it does not seem entirely silly either. For a language so focused on sets, it seems a strange choice.</p>
<h3>They phoned it in</h3>
<p>SQL sometimes really feels like they sat down, thought about <code>SELECT</code>, sub-selects, joins, and the related set algebra, and <em>decided &#8220;nice work&#8221; and <a href="http://www.urbandictionary.com/define.php?term=phone+it+in">phoned the rest in</a></em>. Even <code>INSERT</code> makes no sense, why do we need to seperate the column names from the values?</p>
<pre>INSERT INTO tbl(col1, col2, col3) VALUES(val1, val2, val3)</pre>
<p><code>UPDATE</code> does it right.</p>
<pre>UPDATE tbl SET col1=val1, col2=val2, col3=val3</pre>
<p>Know what&#8217;s being sold as a exciting new feature in SQL 2008? <a href="http://www.vandeputte.org/2007/06/sql-2008-declaring-variables-and.html">Declaring and assigning values in one line!</a>. This is how low the bar is set. SQL is obviously not going anywhere, but I can&#8217;t for the life fathom why it has to be so abysmal at almost everything, except the little core which it does so well.</p>
<p><!--<br />
Transpose tables, WTF. says SQL is masterful in manipulating data my ass.</p>
<p>http://www.sommarskog.se/arrays-in-sql-2005.html</p>
<p>http://msdn.microsoft.com/en-us/library/ms186323(SQL.90).aspx</p>
<p>http://msdn.microsoft.com/en-us/library/ms187748(SQL.90).aspx</p>
<p>http://c2.com/cgi/wiki?ZeroAndOneBasedIndexes</p>
<p>http://c2.com/cgi/wiki?WhyNumberingShouldStartAtZero</p>
<p>http://c2.com/cgi/wiki?OrdinalsAndCardinals</p>
<p>http://databases.aspfaq.com/database/should-i-use-a-temp-table-or-a-table-variable.html</p>
<p>--></p>
]]></content:encoded>
			<wfw:commentRss>http://www.svendtofte.com/geek-angst/sql-split-function/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
