<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Kronester</title>
	
	<link>http://www.kronester.com</link>
	<description>Technisches Tagebuch eines Consultants</description>
	<lastBuildDate>Tue, 15 Dec 2009 11:11:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/FourDragons" /><feedburner:info uri="fourdragons" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-sa/2.5/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><item>
		<title>SQL Injection – Schnelltest</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/Z_OcTbuBGNY/</link>
		<comments>http://www.kronester.com/?p=1000#comments</comments>
		<pubDate>Tue, 15 Dec 2009 11:11:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[ddl]]></category>
		<category><![CDATA[Metadaten]]></category>
		<category><![CDATA[Microsoft Sql Server]]></category>
		<category><![CDATA[replace]]></category>
		<category><![CDATA[schnelltest]]></category>
		<category><![CDATA[sql injection]]></category>

		<guid isPermaLink="false">http://www.kronester.com/?p=1000</guid>
		<description><![CDATA[Um einen evtl. gefährlichen String zu testen, habe ich nachfolgend einen Schnelltest in Form einer Scalar-Funktion entwickelt.
Diese Funktion übernimmt einen potenziell gefährlichen String und prüft ihn auf die wichtigsten Merkmale.

Es dürfen keine String-Hochkommas vorkommen die nicht paarig sind. 
Desweiteren sind DDL-Kommandowörter als potzenziell gefährlich einzustufen. 

Wenn ein "Problem" gefunden wurde, wird eine Fehlermeldung ausgegeben. Im [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-40">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-40');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-40");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p>Um einen evtl. gefährlichen String zu testen, habe ich nachfolgend einen Schnelltest in Form einer Scalar-Funktion entwickelt.</p>
<p>Diese Funktion übernimmt einen potenziell gefährlichen String und prüft ihn auf die wichtigsten Merkmale.</p>
<ul>
<li>Es dürfen keine String-Hochkommas vorkommen die nicht paarig sind. </li>
<li>Desweiteren sind DDL-Kommandowörter als potzenziell gefährlich einzustufen. </li>
</ul>
<p>Wenn ein &#8220;Problem&#8221; gefunden wurde, wird eine Fehlermeldung ausgegeben. Im anderen Fall wird der Originalstring als Rückgabewert präsentiert.</p>
<p>Natürlich erhebt diese Funktion keinen Anspruch auf Vollständigkeit, jedoch ist sie gerade bei der Entwicklung generischer (metadatengesteuerter) Prozeduren für den schnellen Test gerade dieser Metatabellen sehr nützlich.</p>
<p><span id="more-1000"></span>Wenn noch jemand eine Ergänzung hierfür einfällt &#8230; bitte einfach einen kurzen Kommentar posten. Damit bekommen auch andere Besucher dieses Blogs diese Infos mit.</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">FUNCTION</span> dbo.<span style="color: #202020;">SQLInjection_Quicktest</span><span style="color: #808080;">&#40;</span>@Wert <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">RETURNS</span> <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">AS</span></li><li><span style="color: #0000FF;">BEGIN</span></li><li>	<span style="color: #0000FF;">IF</span> <span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>@Wert<span style="color: #808080;">&#41;</span><span style="color: #808080;">-</span><span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Wert,<span style="color: #FF0000;">''</span><span style="color: #FF0000;">''</span>,<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">%</span> 2 <span style="color: #808080;">&lt;&gt;</span> 0</li><li>	<span style="color: #0000FF;">BEGIN</span></li><li>		<span style="color: #0000FF;">SET</span> @Wert <span style="color: #808080;">=</span> <span style="color: #FF0000;">''</span></li><li>		<span style="color: #0000FF;">SET</span> @Wert <span style="color: #808080;">=</span> <span style="color: #FF0000;">'** ERROR - String-Delimiter nicht paarig! **'</span></li><li>	<span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>	<span style="color: #0000FF;">SET</span> @Wert <span style="color: #808080;">=</span> <span style="color: #FF00FF;">LOWER</span><span style="color: #808080;">&#40;</span>@Wert<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>	<span style="color: #0000FF;">IF</span>&nbsp;&nbsp;@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]delete[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]update[^a-z0-9_]%'</span>&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]truncate[^a-z0-9_]%'</span> or</li><li>		@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]drop[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]exec[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]execute[^a-z0-9_]%'</span>&nbsp;&nbsp;or</li><li>		@Wert Like <span style="color: #FF0000;">'%[^a-z0-9_]create[^a-z0-9_]%'</span>&nbsp;&nbsp; or</li><li>&nbsp;</li><li>		@Wert Like <span style="color: #FF0000;">'%delete[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%update[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%truncate[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%drop[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%exec[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or</li><li>		@Wert Like <span style="color: #FF0000;">'%execute[^a-z0-9_]%'</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or</li><li>		@Wert Like <span style="color: #FF0000;">'%create[^a-z0-9_]%'</span></li><li>	<span style="color: #0000FF;">BEGIN</span></li><li>		<span style="color: #0000FF;">SET</span> @Wert <span style="color: #808080;">=</span> <span style="color: #FF0000;">''</span></li><li>		<span style="color: #0000FF;">SET</span> @Wert <span style="color: #808080;">=</span> <span style="color: #FF0000;">'** ERROR - Unzulässiges Schlüsselwort! **'</span></li><li>	<span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>	<span style="color: #0000FF;">RETURN</span> @Wert</li><li><span style="color: #0000FF;">END</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>have fun <img src='http://www.kronester.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/Z_OcTbuBGNY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=1000</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=1000</feedburner:origLink></item>
		<item>
		<title>TSQL Fehler bei Case (simple Version)</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/lS26EE2vPD8/</link>
		<comments>http://www.kronester.com/?p=990#comments</comments>
		<pubDate>Thu, 03 Dec 2009 09:35:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[case]]></category>
		<category><![CDATA[cast]]></category>
		<category><![CDATA[Convert]]></category>
		<category><![CDATA[Expression]]></category>
		<category><![CDATA[rand]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[Tsql]]></category>

		<guid isPermaLink="false">http://www.kronester.com/?p=990</guid>
		<description><![CDATA[Die Case-Anweisung von T-SQL verhält sich sehr interessant (fehlerhaft?) bei Ausdrücken die in der einfachen Version des Statements in der Case-Expression angegeben werden.
Die einfache Syntax siehe wie folgt aus:
CASE input_expression
     WHEN when_expression THEN result_expression
    [ ...n ]
     [
    ELSE else_result_expression
  [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-10">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-10');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-10");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p>Die Case-Anweisung von T-SQL verhält sich sehr interessant (fehlerhaft?) bei Ausdrücken die in der einfachen Version des Statements in der Case-Expression angegeben werden.</p>
<p>Die <strong>einfache Syntax</strong> siehe wie folgt aus:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">CASE</span> input_expression</li><li>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> when_expression <span style="color: #0000FF;">THEN</span> result_expression</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#91;</span> ...<span style="color: #202020;">n</span> <span style="color: #808080;">&#93;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">&#91;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">ELSE</span> else_result_expression</li><li>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">&#93;</span></li><li><span style="color: #0000FF;">END</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Um&nbsp;das Problem&nbsp;zu demonstrieren, möchte ich einmal das folgende Statement zur Diskussion stellen:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">DECLARE</span> @i <span style="color: #0000FF;">INT</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @i <span style="color: #808080;">=</span> 0</li><li>&nbsp;</li><li><span style="color: #0000FF;">WHILE</span> @i<span style="color: #808080;">&lt;</span>10</li><li><span style="color: #0000FF;">BEGIN</span></li><li>	<span style="color: #0000FF;">PRINT</span></li><li>	<span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">INT</span>,<span style="color: #FF00FF;">RAND</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">*</span>5<span style="color: #808080;">+</span>1<span style="color: #808080;">&#41;</span></li><li>		<span style="color: #0000FF;">WHEN</span> 1 <span style="color: #0000FF;">THEN</span> 10</li><li>		<span style="color: #0000FF;">WHEN</span> 2 <span style="color: #0000FF;">THEN</span> 20</li><li>		<span style="color: #0000FF;">WHEN</span> 3 <span style="color: #0000FF;">THEN</span> 30</li><li>		<span style="color: #0000FF;">WHEN</span> 4 <span style="color: #0000FF;">THEN</span> 40</li><li>		<span style="color: #0000FF;">WHEN</span> 5 <span style="color: #0000FF;">THEN</span> 50</li><li>		<span style="color: #0000FF;">WHEN</span> 6 <span style="color: #0000FF;">THEN</span> 60</li><li>		<span style="color: #0000FF;">ELSE</span> 0</li><li>	<span style="color: #0000FF;">END</span></li><li>	<span style="color: #0000FF;">SET</span> @i <span style="color: #808080;">=</span> @i <span style="color: #808080;">+</span> 1</li><li><span style="color: #0000FF;">END</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Das CASE-Statement verwendet die <strong>Random-Funktion RAND().</strong></p>
<p>Diese Funktion liefert Werte zwischen 0 und 1 zurück. Multipliziert man nun den Rückgabewert mit 5 sollten also bis dahin Zahlen zwischen 0 und 5 zurückgeliefert werden. Um 0-Werte auszuschließen wird abschließend noch 1 dazu addiert und der endgültige Wertebereich liegt zwischen 1 und 6.</p>
<p><strong><em>Soweit so gut.</em></strong></p>
<p><span id="more-990"></span></p>
<p>Lässt man jedoch die oben beschriebene Schleife laufen, erhält man als Ergebnis aus dem CASE-Austruck auch den ELSE-Wert 0 zurückgeliefert. Dies darf jedoch aufgrund der Berechnung eigentlich gar nicht geschehen!</p>
<p><strong><em>Das Problem</em></strong> liegt hier in der Art wie die CASE-Funktion die <em>input_expression</em> behandelt. Anscheinend wird der Ausdruck trotz CAST/CONVERT nicht korrekt in seinem Datentyp interpretiert und liefert als Ergebnis wahrscheinlich einen FLOAT-Wert zurück.</p>
<p>(Zur Behandlung von Typkonvertierungen siehe <a href="http://www.kronester.com/?p=920" target="_blank">&#8220;T-SQL CASE und die implizite Datentypkonvertierung&#8221;</a>)</p>
<p>Dieser Wert ist durch die Random-Funktion allerdings nicht im Einzelfall zu bestimmen und kann, wenn überhaupt, nur durch aufwändige Tests ermittelt werden.</p>
<p><strong><em>Als Regel</em></strong> können wir hier also festhalten:</p>
<p style="text-align: center;">Wenn eine CASE-Inputexpression ein nicht deterministisches Ergebnis liefert, ist das Verhalten der Funktion auf das genaueste zu testen.</p>
<p><strong><em>Als Workaround</em></strong> muss man dafür sorgen, dass der Wert für die Inputexpression nicht im CASE berechnet wird, sondern ggf. vorher. Sei es in einer CTE, wenn man den Wert innerhalb einer Abfrage benötigt, oder vorher in einer Variablen.</p>
<p>Ein Beispiel für die Version mit der Variablen findet man nachfolgend:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">DECLARE</span> @i <span style="color: #0000FF;">INT</span></li><li><span style="color: #0000FF;">DECLARE</span> @w <span style="color: #0000FF;">INT</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @i <span style="color: #808080;">=</span> 0</li><li>&nbsp;</li><li><span style="color: #0000FF;">WHILE</span> @i<span style="color: #808080;">&lt;</span>10</li><li><span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @w <span style="color: #808080;">=</span> <span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">INT</span>,<span style="color: #FF00FF;">RAND</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">*</span>5<span style="color: #808080;">+</span>1<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">PRINT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">CASE</span> @w</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> 1 <span style="color: #0000FF;">THEN</span> 10</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> 2 <span style="color: #0000FF;">THEN</span> 20</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> 3 <span style="color: #0000FF;">THEN</span> 30</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> 4 <span style="color: #0000FF;">THEN</span> 40</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> 5 <span style="color: #0000FF;">THEN</span> 50</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WHEN</span> 6 <span style="color: #0000FF;">THEN</span> 60</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">ELSE</span> 0</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @i <span style="color: #808080;">=</span> @i <span style="color: #808080;">+</span> 1</li><li><span style="color: #0000FF;">END</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Wenn jemand einen anderen Weg, oder eine Erklärung für dieses absonderliche Verhalten hat, ist er/sie aufgefordert dies in den Kommentaren der interessierten Öffentlichkeit mitzuteilen.</p>
<p> <img src='http://www.kronester.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/lS26EE2vPD8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=990</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=990</feedburner:origLink></item>
		<item>
		<title>SQL Server: Index Selektivität und UnUsed Indizes</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/RfWgAqVRnMg/</link>
		<comments>http://www.kronester.com/?p=979#comments</comments>
		<pubDate>Wed, 11 Nov 2009 16:29:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[Dynamic management]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[index usage]]></category>
		<category><![CDATA[selectivity]]></category>
		<category><![CDATA[selektivität]]></category>
		<category><![CDATA[Sql Server]]></category>
		<category><![CDATA[sys.dm_db_index_usage_stats]]></category>

		<guid isPermaLink="false">http://www.kronester.com/?p=979</guid>
		<description><![CDATA[
In einer Datenbank können sich über die Zeit sehr viele Tabellen, und damit verbunden auch sehr viele Indizes ansammeln. Möchte man nun wissen welche dieser Indizes noch in Gebrauch sind, kann man dies mittels der Abfrage , wie sie im Beispiel unten gezeigt wird, ermitteln.
In der Dynamic-Management-View sys.dm_db_index_usage_stats sammelt SQL Server Statistikdaten über die Verwendung [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-19">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-19');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-19");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p>In einer Datenbank können sich über die Zeit sehr viele Tabellen, und damit verbunden auch sehr viele Indizes ansammeln. Möchte man nun wissen welche dieser Indizes noch in Gebrauch sind, kann man dies mittels der Abfrage , wie sie im Beispiel unten gezeigt wird, ermitteln.</p>
<p>In der Dynamic-Management-View <strong>sys.dm_db_index_usage_stats</strong> sammelt SQL Server Statistikdaten über die Verwendung eines jeden Indexes der auf der SQL Server Instanz angesprochen wird.</p>
<p><span id="more-979"></span></p>
<p>Dies ist dann auch der Grund warum man die Datenbank im Beispiel (s.u.) explizit im <strong>CTE-Block der Abfrage</strong> angeben muss (@Database).</p>
<p>Die Statistik-Daten werden mit jedem Neustart des MSSQL-Service zurückgesetzt und zeigen daher nur die seit dem letzten Start aufgelaufenen Statistiken an. <strong>Vorsicht</strong> also mit voreiligen Schlüssen was das Löschen von diesen &#8220;unnützen&#8221; Indizes angeht!</p>
<p>Grundsätzlich kann man sich jedoch mal eine Liste ausgeben lassen und die enthaltenen Indizes einer genaueren Prüfung unterziehen.</p>
<p> <img src='http://www.kronester.com/wp-includes/images/smilies/icon_rolleyes.gif' alt=':roll:' class='wp-smiley' /> </p>
<h3>Selektivität oder warum wird mein Index in einer Abfrage nicht verwendet?</h3>
<p>Unter Selektivität eines Index versteht man die Anzahl von Datensätzen die von einem Index-Eintrag angesprochen werden. Je mehr Datensätze über einen Indexschlüssel selektiert würden, je schlechter ist die Selektivität. Der Optimierer von SQL Server bewertet, neben einigen anderen Kriterien, auch die Selektivität eines Index bei der Entscheidung ob dieser Index für eine Abfrage in Betracht gezogen werden muss. Hintergrund ist die triviale Tatsache dass ein Index im Verhältnis zum Scan der gesamten Tabelle ggf. mehr I/O-Aufkommen produzieren würde als der direkte Zugriff auf die Tabelle. Wenn dies der Fall ist, ist ein Table-Scan oft schneller (weil nicht andauernd zwischen Index und Tabelle hin und her gesprungen werden muss um selektierte Daten zu erhalten) als der Zugriff über einen Index.</p>
<p>Grundsätzlich kann man sich die Faustregel, wie im Beispiel dargestellt, zu Herzen nehmen. Da die Selektivität nicht das einzige Kriterium bei der Optimierung ist, kann es durchaus sein das ein Index verwendet wird obwohl die Selektivität schlecht ist.</p>
<p>z.B. wenn der Index die Abfrage komplett abdeckt ist dies meist am schnellsten (schmales Dataset) über den Scan des gesamten Index zu machen.</p>
<p><strong>Also wie immer: den Einzelfall prüfen!</strong></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">USE</span> AdventureWorks</li><li>go</li><li>&nbsp;</li><li><span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">DATABASE</span> sysname</li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">DATABASE</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'AdventureWorks'</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- ----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- unbenutzte Indizes feststellen</span></li><li><span style="color: #008080;">-- ----------------------------------------------------------------</span></li><li>&nbsp;</li><li>;with NotUsed <span style="color: #0000FF;">AS</span></li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span> <span style="color: #FF00FF;">OBJECT_ID</span>,index_id</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">indexes</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">EXCEPT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span> s.<span style="color: #FF00FF;">OBJECT_ID</span>,s.<span style="color: #202020;">index_id</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_db_index_usage_stats</span> s</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">WHERE</span> database_id<span style="color: #808080;">=</span><span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span>@<span style="color: #0000FF;">DATABASE</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SELECT</span> s.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> SchemaName</li><li>&nbsp;&nbsp;&nbsp;&nbsp; , o.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> TabellenName</li><li>&nbsp;&nbsp;&nbsp;&nbsp; , i.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> IndexName</li><li><span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">objects</span> o</li><li>&nbsp;&nbsp;&nbsp;&nbsp;join sys.<span style="color: #202020;">schemas</span> s <span style="color: #0000FF;">ON</span>&nbsp;&nbsp;s.<span style="color: #202020;">schema_id</span> <span style="color: #808080;">=</span> o.<span style="color: #202020;">schema_id</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;join NotUsed n&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">ON</span>&nbsp;&nbsp;o.<span style="color: #FF00FF;">OBJECT_ID</span> <span style="color: #808080;">=</span> n.<span style="color: #FF00FF;">OBJECT_ID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;join sys.<span style="color: #202020;">indexes</span> i <span style="color: #0000FF;">ON</span>&nbsp;&nbsp;i.<span style="color: #202020;">index_id</span>&nbsp;&nbsp;<span style="color: #808080;">=</span> n.<span style="color: #202020;">index_id</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and i.<span style="color: #FF00FF;">OBJECT_ID</span> <span style="color: #808080;">=</span> n.<span style="color: #FF00FF;">OBJECT_ID</span></li><li><span style="color: #0000FF;">WHERE</span> o.<span style="color: #202020;">type</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'U'</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- ----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Faustregel</span></li><li><span style="color: #008080;">-- ----------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- Selektivität eines Index feststellen (excl. Covering-Index)</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- 0 bis 0.05&nbsp;&nbsp;&nbsp;&nbsp; = Hohe Selektivität </span></li><li><span style="color: #008080;">--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Indexverwendung wahrscheinlich)</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- 0.05 bis 0.10&nbsp;&nbsp;= Mittlere Selektivität </span></li><li><span style="color: #008080;">--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IndexVerwendung fraglich)</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- 0,10 und höher = Schlechte Selektivität </span></li><li><span style="color: #008080;">--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Indexverwendung unwahrscheinlich)</span></li><li>&nbsp;</li><li>&nbsp;</li><li><span style="color: #008080;">-- ----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Beispiel: Schlechter selektiver Index</span></li><li><span style="color: #008080;">-- ----------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- select EmailPromotion,count(*) </span></li><li><span style="color: #008080;">-- from Person.Contact </span></li><li><span style="color: #008080;">-- group by EmailPromotion </span></li><li><span style="color: #008080;">-- order by count(*)</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">INDEX</span> IX_Non_Selective <span style="color: #0000FF;">ON</span> Person.<span style="color: #202020;">Contact</span> <span style="color: #808080;">&#40;</span>EmailPromotion<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">DBCC</span> SHOW_STATISTICS <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Person.Contact'</span>,<span style="color: #FF0000;">'IX_Non_Selective'</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">WITH</span> NO_<span style="color: #808080;">IN</span>FOMSGS , DENSITY_VECT<span style="color: #808080;">OR</span> </li><li>&nbsp;</li><li><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span> <span style="color: #0000FF;">FROM</span> Person.<span style="color: #202020;">Contact</span> <span style="color: #0000FF;">WHERE</span> EmailPromotion <span style="color: #808080;">=</span> 2</li><li>&nbsp;</li><li><span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">INDEX</span> IX_Non_Selective <span style="color: #0000FF;">ON</span> Person.<span style="color: #202020;">Contact</span> </li><li>&nbsp;</li><li><span style="color: #008080;">-- ----------------------------------------------------------------</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>have fun <img src='http://www.kronester.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/RfWgAqVRnMg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=979</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=979</feedburner:origLink></item>
		<item>
		<title>SET OPTIONs abfragen und SSIS-Probleme vermeiden</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/-fbugAZ1JAM/</link>
		<comments>http://www.kronester.com/?p=973#comments</comments>
		<pubDate>Thu, 22 Oct 2009 08:14:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>

		<guid isPermaLink="false">http://www.kronester.com/?p=973</guid>
		<description><![CDATA[

Im vorliegenden Fall hatte ich ein Problem mit einem SSIS-Paket dass mit einer Fehlermeldung abgebrochen wurde. Die Fehlermeldung besagte, dass es eine Warnung beim Aufruf der Datenquelle (View) gegeben hätte.

Diese Warnung sollte nach meiner Meinung auch als Warnung und nicht als Fehler behandelt werden. Das Problem war leicht zu beheben, ich musste nur ein Set-Kommando [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-66">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-66');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-66");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p>Im vorliegenden Fall hatte ich ein Problem mit einem SSIS-Paket dass mit einer Fehlermeldung abgebrochen wurde. Die Fehlermeldung besagte, dass es eine Warnung beim Aufruf der Datenquelle (View) gegeben hätte.</p>
<p>Diese Warnung sollte nach meiner Meinung auch als Warnung und nicht als Fehler behandelt werden. Das Problem war leicht zu beheben, ich musste nur ein Set-Kommando vor der View platzieren dass die ANSI_WARNINGS abschaltet.</p>
<p>
<!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">SET</span> ANSI_WARN<span style="color: #808080;">IN</span>GS <span style="color: #0000FF;">OFF</span></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p>Der View Aufruf liefert jetzt den Returncode 0 zurück und das Paket tut das was es immer hätte tun sollen.</p>
<p>Im Nachhinein stellte sich mir jedoch die Frage, welche SET-Options denn eigentlich für eine aktuell ausgeführte Session gerade aktiv sind und wie diese abgefragt werden können?</p>
<p><span id="more-973"></span>Für diesen Zweck stellt SQL-Server die Variable <strong>@@OPTIONS</strong> zur Verfügung. Hier kann man über eine bitweise UND-Verknüpfung den Status der verschiedenen SET-Optionen bestimmen.</p>
<p>Da mir dies jedoch für den wiederholten Gebrauch zu unhandlich erschien, habe ich mal eben eine kleine Funktion geschrieben die den Status aller Optionen in einer Tabelle zurückliefert:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">FUNCTION</span> fn_Get_SetOptions<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">RETURNS</span> <span style="color: #0000FF;">TABLE</span></li><li><span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">RETURN</span></li><li><span style="color: #0000FF;">WITH</span> Options <span style="color: #0000FF;">AS</span></li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0001<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0001<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> DISABLE_DEF_CNST_CHK</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0002<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0002<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> IMPLICIT_TRANSACTIONS</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0004<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0004<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> CURS<span style="color: #808080;">OR</span>_CLOSE_ON_COMMIT</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0008<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0008<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ANSI_WARN<span style="color: #808080;">IN</span>GS</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0010<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0010<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ANSI_PADD<span style="color: #808080;">IN</span>G</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0020<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0020<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ANSI_<span style="color: #808080;">NULL</span>S</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0040<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0040<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ARITHAB<span style="color: #808080;">OR</span>T</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0080<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0080<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ARITHIGN<span style="color: #808080;">OR</span>E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0100<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0100<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> QUOTED_IDENTIFIER</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0200<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0200<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">NOCOUNT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0400<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0400<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ANSI_<span style="color: #808080;">NULL</span>_DFLT_ON</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x0800<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x0800<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> ANSI_<span style="color: #808080;">NULL</span>_DFLT_OFF</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x1000<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x1000<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> CONCAT_<span style="color: #808080;">NULL</span>_YIELDS_<span style="color: #808080;">NULL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x2000<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x2000<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> NUMERIC_ROUNDAB<span style="color: #808080;">OR</span>T</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">BIT</span>,<span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@OPTIONS</span> <span style="color: #808080;">&amp;</span> 0x4000<span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> 0x4000<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> XACT_AB<span style="color: #808080;">OR</span>T</li><li><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span> <span style="color: #0000FF;">FROM</span> </li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span> <span style="color: #0000FF;">FROM</span> Options </li><li>&nbsp;&nbsp;&nbsp;&nbsp;unpivot </li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsSet <span style="color: #0000FF;">FOR</span> SetOption in </li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DISABLE_DEF_CNST_CHK</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,IMPLICIT_TRANSACTIONS</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,CURS<span style="color: #808080;">OR</span>_CLOSE_ON_COMMIT</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ANSI_WARN<span style="color: #808080;">IN</span>GS</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ANSI_PADD<span style="color: #808080;">IN</span>G</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ANSI_<span style="color: #808080;">NULL</span>S</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ARITHAB<span style="color: #808080;">OR</span>T</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ARITHIGN<span style="color: #808080;">OR</span>E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,QUOTED_IDENTIFIER</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<span style="color: #0000FF;">NOCOUNT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ANSI_<span style="color: #808080;">NULL</span>_DFLT_ON</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ANSI_<span style="color: #808080;">NULL</span>_DFLT_OFF</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,CONCAT_<span style="color: #808080;">NULL</span>_YIELDS_<span style="color: #808080;">NULL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,NUMERIC_ROUNDAB<span style="color: #808080;">OR</span>T</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,XACT_AB<span style="color: #808080;">OR</span>T</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#41;</span> unpvt</li><li><span style="color: #808080;">&#41;</span> x</li><li>GO</li><li>&nbsp;</li><li><span style="color: #008080;">-- ---------------- So wird die Funktion aufgerufen ------------------</span></li><li><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span> <span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&#91;</span>AdventureWorks<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>fn_Get_SetOptions<span style="color: #808080;">&#93;</span> <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Hier noch die Values für die verschiedenen SET-Optionen zum selber verknüpfen:</p>
<table style="width: 444px; height: 322px;" border="0">
<caption>Werte für die Bestimmung von SET-Optionen aus der @@Options-Variable</caption>
<tbody>
<tr>
<td style="text-align: right;">1</td>
<td>
<p>DISABLE_DEF_CNST_CHK</p>
</td>
</tr>
<tr>
<td style="text-align: right;">2</td>
<td>
<p>IMPLICIT_TRANSACTIONS</p>
</td>
</tr>
<tr>
<td style="text-align: right;">4</td>
<td>
<p>CURSOR_CLOSE_ON_COMMIT</p>
</td>
</tr>
<tr>
<td style="text-align: right;">8</td>
<td>
<p>ANSI_WARNINGS</p>
</td>
</tr>
<tr>
<td style="text-align: right;">16</td>
<td>
<p>ANSI_PADDING</p>
</td>
</tr>
<tr>
<td style="text-align: right;">32</td>
<td>
<p>ANSI_NULLS</p>
</td>
</tr>
<tr>
<td style="text-align: right;">64</td>
<td>
<p>ARITHABORT</p>
</td>
</tr>
<tr>
<td style="text-align: right;">128</td>
<td>
<p>ARITHIGNORE</p>
</td>
</tr>
<tr>
<td style="text-align: right;">256</td>
<td>
<p>QUOTED_IDENTIFIER</p>
</td>
</tr>
<tr>
<td style="text-align: right;">512</td>
<td>
<p>NOCOUNT</p>
</td>
</tr>
<tr>
<td style="text-align: right;">1024</td>
<td>
<p>ANSI_NULL_DFLT_ON</p>
</td>
</tr>
<tr>
<td style="text-align: right;">2048</td>
<td>
<p>ANSI_NULL_DFLT_OFF</p>
</td>
</tr>
<tr>
<td style="text-align: right;">4096</td>
<td>
<p>CONCAT_NULL_YIELDS_NULL</p>
</td>
</tr>
<tr>
<td style="text-align: right;">8192</td>
<td>
<p>NUMERIC_ROUNDABORT</p>
</td>
</tr>
<tr>
<td style="text-align: right;">16384</td>
<td>
<p>XACT_ABORT</p>
</td>
</tr>
</tbody>
</table>
<p>have fun </p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/-fbugAZ1JAM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=973</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=973</feedburner:origLink></item>
		<item>
		<title>Funktionsergebnisse mit cross/outer apply einbinden</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/jqRJmHIVwhI/</link>
		<comments>http://www.kronester.com/?p=964#comments</comments>
		<pubDate>Wed, 21 Oct 2009 08:59:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[cross apply]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[funktion]]></category>
		<category><![CDATA[Microsoft Sql Server]]></category>
		<category><![CDATA[outer apply]]></category>
		<category><![CDATA[T-Sql]]></category>
		<category><![CDATA[table valued function]]></category>
		<category><![CDATA[Tsql]]></category>
		<category><![CDATA[tvf]]></category>

		<guid isPermaLink="false">http://web3.698.bces.de/?p=964</guid>
		<description><![CDATA[Ich möchte heute eine interessante Methode vorstellen die es ermöglicht die Ergebnisse von Funktionen in SQL-Abfragen zu verwenden.
Die sogenannten Table-Values-Functions (Funktionen die eine Tabelle als Return-Wert haben) können bei Abfragen wie eine Tabelle in ein Select-Statement eingebunden werden. Parameterwerte dürfen jedoch bei einem normalen Join nur von außerhalb des Select-Statements versorgt werden.
Als Beispiel könnte die [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-89">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-89');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-89");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p>Ich möchte heute eine interessante Methode vorstellen die es ermöglicht die Ergebnisse von Funktionen in SQL-Abfragen zu verwenden.</p>
<p>Die sogenannten Table-Values-Functions (Funktionen die eine Tabelle als Return-Wert haben) können bei Abfragen wie eine Tabelle in ein Select-Statement eingebunden werden. Parameterwerte dürfen jedoch bei einem normalen Join nur von außerhalb des Select-Statements versorgt werden.</p>
<p>Als Beispiel könnte die in der AdventureWorks enthaltene Funktion <span style="font-family: andale mono,times;">dbo.ufnGetContactInformation </span>in einer Abfrage verwendet werden. Als Parameterwert kann die <span style="font-family: andale mono,times;">ContactID</span> einer Person übergeben werden und die TVF (Table-Valued-Function) liefert ein paar Kontaktdaten (Name, Vorname, Position, KontaktArt) zurück.</p>
<p>Möchte man diese Funktionalität nun in einem Select verwenden, ist man versucht die TVF, die ja wie eine Tabelle behandelt werden kann, wie folgt einzusetzen:</p>
<p><span style="color: #800000;"><strong>Nicht Korrekt!</strong></span></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">WITH</span> Liste <span style="color: #0000FF;">AS</span></li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; SalesPersonID</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>TotalDue<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> TotalDue</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FROM</span> Sales.<span style="color: #202020;">SalesOrderHeader</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">GROUP</span> <span style="color: #0000FF;">BY</span>&nbsp;&nbsp;SalesPersonID</li><li><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; ci.<span style="color: #202020;">FirstName</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ci.<span style="color: #202020;">LastName</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ci.<span style="color: #202020;">JobTitle</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ci.<span style="color: #202020;">ContactType</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, l.<span style="color: #202020;">TotalDue</span></li><li><span style="color: #0000FF;">FROM</span> Liste l</li><li>join HumanResources.<span style="color: #202020;">Employee</span> e </li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">ON</span> e.<span style="color: #202020;">EmployeeID</span> <span style="color: #808080;">=</span> l.<span style="color: #202020;">SalesPersonID</span></li><li>join dbo.<span style="color: #202020;">ufnGetContactInformation</span><span style="color: #808080;">&#40;</span>e.<span style="color: #202020;">ContactID</span><span style="color: #808080;">&#41;</span> ci </li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">ON</span> ci.<span style="color: #202020;">ContactID</span> <span style="color: #808080;">=</span> e.<span style="color: #202020;">ContactID</span></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p><span id="more-964"></span></p>
<p>In dem obigen Beispiel wird man eine Fehlermeldung bekommen, da hier versucht wird einen Parameterwert aus dem laufenden Select zu verwenden bzw. die TVF als JOIN-Tabelle genutzt wird.</p>
<p>Um eine TVF zu einem Select-Bestand zu joinen, muss stattdessen die Variante mittels APPLY gewählt werden. Hier gibt es zwei Möglichkeiten die einem INNER bzw. OUTER JOIN entsprechen.</p>
<p>Mittels CROSS APPLY wird das Ergebnis der TVF an das bestehende Resultset angehängt. Das Verhalten entspricht hier einem INNER JOIN, da Datensätze die kein Ergebnis über die Funktion liefern, nicht im Ausgabeset enthalten sind.</p>
<p>Möchte man, wie bei einem OUTER JOIN, alle Datensätze der Abfrage erhalten so muss die OUTER APPLY Variante angewendet werden. Spalten die nicht durch die TVF gefüllt werden können, werden hierbei mit NULL-Werten gefüllt.</p>
<p>Hier jetzt das korrekte Statement. Es zeigt die Umsätze aller Vertriebsmitarbeiter an. Direkte Kundenumsätze werden hierbei durch den CROSS APPLY unterdrückt.</p>
<p><strong><span style="color: #008080;">Korrekte Anwendung</span></strong></p>
<p>
<!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">WITH</span> Liste <span style="color: #0000FF;">AS</span></li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; SalesPersonID</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>TotalDue<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> TotalDue</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FROM</span> Sales.<span style="color: #202020;">SalesOrderHeader</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">GROUP</span> <span style="color: #0000FF;">BY</span>&nbsp;&nbsp;SalesPersonID</li><li><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; ci.<span style="color: #202020;">FirstName</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ci.<span style="color: #202020;">LastName</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ci.<span style="color: #202020;">JobTitle</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ci.<span style="color: #202020;">ContactType</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, l.<span style="color: #202020;">TotalDue</span></li><li><span style="color: #0000FF;">FROM</span> Liste l</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">LEFT</span> join HumanResources.<span style="color: #202020;">Employee</span> e <span style="color: #0000FF;">ON</span> e.<span style="color: #202020;">EmployeeID</span> <span style="color: #808080;">=</span> l.<span style="color: #202020;">SalesPersonID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;cross apply dbo.<span style="color: #202020;">ufnGetContactInformation</span><span style="color: #808080;">&#40;</span>e.<span style="color: #202020;">ContactID</span><span style="color: #808080;">&#41;</span> ci</li><li>&nbsp;</li><li><span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> LastName</li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p>Man kann ja mal das selbe Statement mit OUTER APPLY probieren <img src='http://www.kronester.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>have fun</p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/jqRJmHIVwhI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=964</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=964</feedburner:origLink></item>
		<item>
		<title>Parent-Child Tabellen für Reports sortieren</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/XGPN1BOYAqk/</link>
		<comments>http://www.kronester.com/?p=957#comments</comments>
		<pubDate>Tue, 13 Oct 2009 16:14:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[Cte]]></category>
		<category><![CDATA[Microsoft Sql Server]]></category>
		<category><![CDATA[parent-child]]></category>
		<category><![CDATA[rekursiv]]></category>
		<category><![CDATA[rekursive berichte]]></category>
		<category><![CDATA[SSRS]]></category>

		<guid isPermaLink="false">http://web3.698.bces.de/?p=957</guid>
		<description><![CDATA[
Wenn man eine Parent-Child-Tabelle für einen Report vorbereiten soll, so ist das nicht immer ganz einfach. Die Parent-Child-Hierarchy kann man zwar noch mit einer rekursiven CTE (common table expression) abfragen, jedoch ist die anschließende Sortierung des Resultsets ein nicht zu unterschätzendes Hindernis.
Die CTE-Abfrage liefert zwar die richtigen Datensätze, gibt sie aber nicht in einer, für [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-70">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-70');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-70");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p>Wenn man eine Parent-Child-Tabelle für einen Report vorbereiten soll, so ist das nicht immer ganz einfach. Die Parent-Child-Hierarchy kann man zwar noch mit einer rekursiven CTE (common table expression) abfragen, jedoch ist die anschließende Sortierung des Resultsets ein nicht zu unterschätzendes Hindernis.</p>
<p>Die CTE-Abfrage liefert zwar die richtigen Datensätze, gibt sie aber nicht in einer, für den Report geeigneten Weise, zurück.</p>
<p>Beispiel eines Ergebnis-Sets für eine Abfrage der Personal-Hierarchy aus der AdventureWorks:</p>
<p><pre>Title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EmployeeID&nbsp; ManagerID&nbsp;&nbsp;&nbsp; Level
------------------------------- ----------- -----------&nbsp; ------
Chief Executive Officer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp; &nbsp;
Marketing Manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
Vice President of Engineering&nbsp;&nbsp; 12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
Information Services Manager&nbsp;&nbsp;&nbsp; 42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
Chief Financial Officer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
Vice President of Production&nbsp;&nbsp;&nbsp; 148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
Vice President of Sales&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 273&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
North American Sales Manager&nbsp;&nbsp;&nbsp; 268&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 273&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp; &nbsp;
European Sales Manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 284&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 273&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp; &nbsp;
Pacific Sales Manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 288&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 273&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp; &nbsp;
Sales Representative&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 290&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 288&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Sales Representative&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 285&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 284&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Sales Representative&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 286&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 284&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Sales Representative&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 289&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 284&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Sales Representative&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 275&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 268&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;
</pre></p>
<p><span id="more-957"></span></p>
<p>Wie man hier sehen kann, werden die unterschiedlichen Hierarchy-Level sortiert dargestellt.</p>
<p>Für einen Bericht müsste man dieses Ergebnis umsortieren bzw. in der folgenden Reihenfolge zurückgeliefert bekommen:</p>
<p><pre>Title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EmployeeID&nbsp; ManagerID&nbsp;&nbsp; LoginID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Level
---------------------------------- ----------- ----------- ---------------------------- ------
Chief Executive Officer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\ken0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp; &nbsp;
Vice President of Engineering&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\terri0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; &nbsp;
Engineering Manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\roberto0&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp; &nbsp;
Design Engineer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\jossef0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Research and Development Manager&nbsp;&nbsp; 158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\dylan0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Research and Development Engineer&nbsp; 114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\gigi0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp; &nbsp;
Research and Development Manager&nbsp;&nbsp; 217&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\michael6&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp; &nbsp;
Research and Development Engineer&nbsp; 79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\diane1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp; &nbsp;
Senior Tool Designer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 263&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\ovidiu0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp; &nbsp;
Tool Designer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 265&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 263&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\janice0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp; &nbsp;
Tool Designer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 263&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\thierry0&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp; &nbsp;
Senior Design Engineer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 267&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adventure-works\michael8&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;
</pre></p>
<p>&nbsp;</p>
<p>Hier ist die Reihenfolge, beginnend mit einem Manager ab Level 1 für diesen einen Manager bis zum Boden definiert. Danach wird zur nächst höheren Ebene zurückverwiesen die wiederum weitere Untergebene hat. Das Ergebnis wird also so angezeigt, wie dies in einem Bericht normalerweise stattfinden sollte.</p>
<p>Diese Sortierung kann man bereits bei der Generierung der Hierarchy als extra Feld mit in die rekursive Abfrage einbauen. Man benötigt hierfür ein Feld dass sortierbar ist und für den individuellen Zweck auch geeignet scheint.</p>
<p>Ich hab für das Beispiel einfach die EmployeeID verwendet. Wenn man diese ID je Ebene jeweils mit den IDs der Vorgesetzten versieht dann erhält man in etwa die folgende Spalte:</p>
<p><pre>Hierarchy
--------------
109
1096
10912
10942
109140
109148
109273
109273268
109273284
109273288
109273288290
109273284285
109273284286
109273284289
109273268275</pre></p>
<p>&nbsp;</p>
<p>Sortiert man das Ergebnis nach dieser Hierarchy-Spalte und rückt das Resultset je nach Level noch ein wird die Hierarchy schnell sichtbar.</p>
<p><pre>| Chief Executive Officer (109)
————— Vice President of Engineering (12)
————————— Engineering Manager (3)
————————————— Design Engineer (11)
————————————— Research and Development Manager (158)
————————————————— Research and Development Engineer (114)
————————————————— Research and Development Manager (217)
————————————————— Research and Development Engineer (79)
————————————— Senior Tool Designer (263)
————————————————— Tool Designer (265)
————————————————— Tool Designer (5)
————————————— Senior Design Engineer (267)
————————————— Design Engineer (270)
————————————— Senior Tool Designer (4)
————————————— Design Engineer (9)
————— Chief Financial Officer (140)
————————— Assistant to the Chief Financial Officer (103)
————————— Accounts Manager (139)
————————————— Accounts Receivable Specialist (130)
————————————— Accounts Payable Specialist (166)</pre></p>
<p>&nbsp;</p>
<p>Das Ergebnis enthält ja die EmployeeID und kann somit mit weiteren Tabellen verjoint werden und für einen Bericht sozusagen Mundgerecht aufbereitet werden. Die Sortierung innerhalb der Ebenen erfolgt im Moment noch über die EmployeeID, könne jedoch ggf. noch durch die JobBezeichung ergänzt werden. Dies würde die einzelnen Tätigkeiten auf den inneren Ebenen noch ein wenig gruppieren.</p>
<p>Wie immer hier das komplette Listing:</p>
<p>
<!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">USE</span> AdventureWorks</li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">DECLARE</span> @EmployeeID <span style="color: #0000FF;">INT</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- ------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- CEO bestimmen (Start der Hierarchy)</span></li><li><span style="color: #008080;">-- ------------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SELECT</span> @EmployeeID <span style="color: #808080;">=</span> EmployeeID</li><li><span style="color: #0000FF;">FROM</span> HumanResources.<span style="color: #202020;">Employee</span></li><li><span style="color: #0000FF;">WHERE</span> ManagerID <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- ------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Parent-Child Struktur parsen und einen sortierbaren Schlüssel</span></li><li><span style="color: #008080;">-- aufbauen.</span></li><li><span style="color: #008080;">-- In diesem Beispiel ist dies die EmployeeID, könnte auch jedes</span></li><li><span style="color: #008080;">-- andere Feld sein das eine Sortierung möglich machen könnte.</span></li><li><span style="color: #008080;">-- ------------------------------------------------------------------</span></li><li>&nbsp;</li><li>;WITH ParentChildHierachy <span style="color: #0000FF;">AS</span></li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; emp.<span style="color: #202020;">Title</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,emp.<span style="color: #202020;">EmployeeID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,emp.<span style="color: #202020;">ManagerID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,emp.<span style="color: #202020;">LoginID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,0 <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">LEVEL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span>,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>10<span style="color: #808080;">&#41;</span>,emp.<span style="color: #202020;">EmployeeID</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> Hierarchy</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FROM</span> HumanResources.<span style="color: #202020;">Employee</span> emp</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">WHERE</span> emp.<span style="color: #202020;">EmployeeID</span> <span style="color: #808080;">=</span> @EmployeeID&nbsp;&nbsp;</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">UNION</span> <span style="color: #808080;">ALL</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; emp.<span style="color: #202020;">Title</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,emp.<span style="color: #202020;">EmployeeID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,emp.<span style="color: #202020;">ManagerID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,emp.<span style="color: #202020;">LoginID</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,pch.<span style="color: #0000FF;">LEVEL</span><span style="color: #808080;">+</span>1</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span>,pch.<span style="color: #202020;">Hierarchy</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">+</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>10<span style="color: #808080;">&#41;</span>,emp.<span style="color: #202020;">EmployeeID</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> Hierarchy</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FROM</span> HumanResources.<span style="color: #202020;">Employee</span> emp</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;join ParentChildHierachy pch <span style="color: #0000FF;">ON</span> pch.<span style="color: #202020;">EmployeeID</span> <span style="color: #808080;">=</span> emp.<span style="color: #202020;">ManagerID</span></li><li><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SELECT</span>&nbsp;&nbsp; Title</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,EmployeeID</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,ManagerID</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,LoginID</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<span style="color: #0000FF;">LEVEL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,Hierarchy</li><li><span style="color: #0000FF;">INTO</span> #TempTable</li><li><span style="color: #0000FF;">FROM</span> ParentChildHierachy</li><li><span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span> Hierarchy</li><li>&nbsp;</li><li><span style="color: #008080;">-- ------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Ausgabe der Hierarchie in Druckbarer Form</span></li><li><span style="color: #008080;">-- ------------------------------------------------------------------</span></li><li>&nbsp;</li><li>&nbsp;</li><li><span style="color: #0000FF;">DECLARE</span> @Title <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>1000<span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">LEVEL</span> <span style="color: #0000FF;">INT</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">DECLARE</span> c1 <span style="color: #0000FF;">CURSOR</span> <span style="color: #0000FF;">FOR</span></li><li><span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">LEVEL</span>,Title,EmployeeID <span style="color: #0000FF;">FROM</span> #TempTable</li><li>&nbsp;</li><li><span style="color: #0000FF;">OPEN</span> c1</li><li>&nbsp;</li><li><span style="color: #0000FF;">FETCH</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">FROM</span> c1 <span style="color: #0000FF;">INTO</span> @<span style="color: #0000FF;">LEVEL</span>, @Title, @EmployeeID</li><li>&nbsp;</li><li><span style="color: #0000FF;">WHILE</span> <span style="color: #FF00FF;">@@FETCH_STATUS</span> <span style="color: #808080;">=</span> 0</li><li><span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">PRINT</span> <span style="color: #0000FF;">CASE</span> @<span style="color: #0000FF;">LEVEL</span> <span style="color: #0000FF;">WHEN</span> 0 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'|'</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span>151<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">END</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLICATE</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span>151<span style="color: #808080;">&#41;</span>,@<span style="color: #0000FF;">LEVEL</span><span style="color: #808080;">*</span><span style="color: #000;">4</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">+</span> <span style="color: #FF0000;">' '</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">+</span> @Title</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">+</span> <span style="color: #FF0000;">' ('</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>,@EmployeeID<span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">')'</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">FETCH</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">FROM</span> c1 <span style="color: #0000FF;">INTO</span> @<span style="color: #0000FF;">LEVEL</span>, @Title, @EmployeeID</li><li><span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">CLOSE</span> c1</li><li><span style="color: #0000FF;">DEALLOCATE</span> c1</li><li>&nbsp;</li><li><span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">TABLE</span> #TempTable</li><li></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p>have fun</p>
<p> <img src='http://www.kronester.com/wp-includes/images/smilies/icon_cool.gif' alt='8-)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/XGPN1BOYAqk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=957</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=957</feedburner:origLink></item>
		<item>
		<title>T-SQL Stringhandling (Extraktion von Token)</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/5C74VI8LUtc/</link>
		<comments>http://www.kronester.com/?p=932#comments</comments>
		<pubDate>Fri, 25 Sep 2009 14:03:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[charindex]]></category>
		<category><![CDATA[datalength]]></category>
		<category><![CDATA[patindex]]></category>
		<category><![CDATA[Sql Server]]></category>
		<category><![CDATA[strings]]></category>
		<category><![CDATA[T-Sql]]></category>
		<category><![CDATA[token]]></category>
		<category><![CDATA[Tsql]]></category>

		<guid isPermaLink="false">http://www.kroni.de/?p=932</guid>
		<description><![CDATA[Heute möchte ich einmal ein kleines Script bzw. eine kleine Funktion vorstellen die zum Zerlegen von Strings sehr nützlich sein kann.
Wenn man strukturierte Texte vorliegen hat und daraus bestimmte Teile extrahieren soll, so kann man dies sicher mit den Stringfunktionen von T-SQL erledigen. Gerade die Verarbeitung von Listen (Kommasepariert oder sonst irgendwie) bedingt aber die [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-57">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-57');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-57");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p>Heute möchte ich einmal ein kleines Script bzw. eine kleine Funktion vorstellen die zum Zerlegen von Strings sehr nützlich sein kann.</p>
<p>Wenn man strukturierte Texte vorliegen hat und daraus bestimmte Teile extrahieren soll, so kann man dies sicher mit den Stringfunktionen von T-SQL erledigen. Gerade die Verarbeitung von Listen (Kommasepariert oder sonst irgendwie) bedingt aber die wiederholte Extraktion von Textblöcken (Token) die durch verschiedenste Begrenzungszeichen voneinander getrennt sind.</p>
<p>Als Token verstehe ich in diesem Zusammenhang Teile eines Textes die durch Begrenzer (Delimiter) voneinander logisch getrennt werden. In einem Satz wären das die Worte, in einer Liste die durch z.B. Komma getrennten Artikelnummern oder einfach Bestandteile eines Tabellennamens usw.</p>
<p>Sehen wir uns hierzu mal ein paar <strong>Beispiele </strong>an:</p>
<ul>
<li>String: &#8216;Hello World, how are you?&#8217;</li>
<li>String: &#8216;123,2345,231234,3456&#8242;</li>
<li>String: &#8216;[AdventureWorks].[Person].  [Contact]&#8216;</li>
</ul>
<p>Extrahieren wir mal das dritte Wort aus Beispiel 1, den zweiten Parameterwert aus Beispiel 2 und den Tabellennamen aus Beispiel 3!</p>
<p>Mit Standardmitteln sicherlich ebenfalls zu realisieren, jedoch mit einer Funktion viel eleganter und Übersichtlicher zu gestalten:</p>
<p><span id="more-932"></span></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">DECLARE</span> @String1 <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>1000<span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @String2 <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>1000<span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @String3 <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1000</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- --------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Single Delimiter ' ' Leerzeichen</span></li><li><span style="color: #008080;">-- --------------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @String1 <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Hello World, how are you?'</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">PRINT</span> @String1 <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&nbsp;&nbsp;==&gt;&nbsp;&nbsp;'</span> <span style="color: #808080;">+</span> dbo.<span style="color: #202020;">fn_GetToken</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">' '</span>,<span style="color: #000;">3</span>,@String<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- --------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Single Delimiter ',' Komma</span></li><li><span style="color: #008080;">-- --------------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @String2 <span style="color: #808080;">=</span> <span style="color: #FF0000;">'123,2345,231234,3456'</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">PRINT</span> @String2 <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&nbsp;&nbsp;==&gt;&nbsp;&nbsp;'</span> <span style="color: #808080;">+</span> dbo.<span style="color: #202020;">fn_GetToken</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">','</span>,<span style="color: #000;">2</span>,@String<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- --------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Paariger Delimiter []</span></li><li><span style="color: #008080;">-- --------------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @String3 <span style="color: #808080;">=</span> <span style="color: #FF0000;">'[AdventureWorks].[Person].&lt;leerzeichen&gt;[Contact]'</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">PRINT</span> @String3 <span style="color: #808080;">+</span> <span style="color: #FF0000;">'&nbsp;&nbsp;==&gt;&nbsp;&nbsp;'</span> <span style="color: #808080;">+</span> dbo.<span style="color: #202020;">fn_GetToken</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'[&lt;-*-&gt;]'</span>,<span style="color: #000;">3</span>,@String<span style="color: #808080;">&#41;</span></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p>Die Syntax für den&nbsp;Fuktionsaufruf sieht dann wie folgt aus:</p>
<p><pre style="font-size:1.2em;font-weigth:bold;">dbo.fn_GetToken(single_delimiter|delimiter_pair, position, source_string)</pre></p>
<ul>
<li><strong>single_delimiter:</strong>&nbsp;Beliebige Zeichenkette&nbsp;die Token voneinander trennt.</li>
<li><strong>delimiter_pair</strong>: Beliebige Zeichenkette, danach ein Trennblock <strong><span style="background-color: #ffcc99;"><-*-></span></strong> und dann wieder eine Zeichenkette.</li>
<li><strong>position:</strong> Das n-te Token beginnend mit 1. <br />Wenn position = 0 dann wird der String unverändert returniert.</li>
<li><strong>source_string:</strong> Der Quellstring.</li>
<li>Als <strong>Rückgabewert</strong> wird das Token ohne die Delimiter geliefert oder NULL im Fehlerfall.</li>
</ul>
<p>&#8230; und hier wie immer das Script dazu:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">FUNCTION</span> dbo.<span style="color: #808080;">&#91;</span>fn_GetToken<span style="color: #808080;">&#93;</span></li><li><span style="color: #808080;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Delim <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span>100<span style="color: #808080;">&#41;</span>,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@TokenNr <span style="color: #0000FF;">INT</span>,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Zeile <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">RETURNS</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">AS</span></li><li><span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @RetWert&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Line&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span>	</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @End_Delim&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span>100<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @End_Delim_Len&nbsp;&nbsp;<span style="color: #0000FF;">INT</span>			</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Delim_Pos_S&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">INT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Delim_Pos_E&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">INT</span>			</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Delim_S <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span>100<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Delim_E <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span>100<span style="color: #808080;">&#41;</span>	</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Pos&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">INT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @<span style="color: #FF00FF;">LEN</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">INT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Delim_Len&nbsp;&nbsp;<span style="color: #0000FF;">INT</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @TokenCnt&nbsp;&nbsp; <span style="color: #0000FF;">INT</span>		</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Initialisierung der Parameter auf Defaults</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @Zeile&nbsp;&nbsp; <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #0000FF;">SET</span> @Zeile&nbsp;&nbsp; <span style="color: #808080;">=</span> N<span style="color: #FF0000;">''</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @Delim&nbsp;&nbsp; <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #0000FF;">SET</span> @Delim&nbsp;&nbsp; <span style="color: #808080;">=</span> N<span style="color: #FF0000;">';'</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @TokenNr <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #0000FF;">SET</span> @TokenNr <span style="color: #808080;">=</span> 1</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Line <span style="color: #808080;">=</span> @Zeile</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Anfangs- und Ende-Delimiter bestimmen wenn die Zeichenfolge</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- '&lt;-*-&gt;' im Delimiter vorhanden ist.</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Im anderen Fall wird die Zeichenfolge als Einzeldelimiter verwendet.</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'&lt;-*-&gt;'</span>,@Delim<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> 0</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @End_Delim <span style="color: #808080;">=</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Delim,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'&lt;-*-&gt;'</span>,@Delim<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">+</span>5,datalength<span style="color: #808080;">&#40;</span>@Delim<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span>2<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Delim,1,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span>N<span style="color: #FF0000;">'&lt;-*-&gt;'</span>,@Delim<span style="color: #808080;">&#41;</span><span style="color: #808080;">-</span>1<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">ELSE</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @End_Delim <span style="color: #808080;">=</span> @Delim</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Die Länge des Begrenzers muss halbiert werden (Unicode)</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_Len&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">=</span> datalength<span style="color: #808080;">&#40;</span>@Delim<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span>2</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @End_Delim_Len <span style="color: #808080;">=</span> datalength<span style="color: #808080;">&#40;</span>@End_Delim<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span><span style="color: #000;">2</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Start und Ende setzen. Wenn nur ein Begrenzer definiert ist,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- dann sind Start und Ende gleich.</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_S <span style="color: #808080;">=</span> @Delim</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_E <span style="color: #808080;">=</span> @End_Delim</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Die eckige Klammer muss als regulärer Ausdruck gecastet werden.</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Aus [ wird [[]</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Delim&nbsp;&nbsp;&nbsp;&nbsp;,N<span style="color: #FF0000;">'['</span>,<span style="color: #FF0000;">'[[]'</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @End_Delim <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@End_Delim,N<span style="color: #FF0000;">'['</span>,<span style="color: #FF0000;">'[[]'</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Wenn es nur einen Delimiter gibt, muss die ganze Zeile auf eine</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Zwei-Delimiter-Logik erweitert werden</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Dies bedeutet, dass die Zeile von einem Start und Enddelimiter</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- umschlossen sein muss. Diese Werte werden ggf. hinzugefügt.</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @Delim_S <span style="color: #808080;">=</span> @Delim_E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Zeile,1,@Delim_Len&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&lt;&gt;</span> @Delim_S</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Zeile <span style="color: #808080;">=</span> @Delim_S <span style="color: #808080;">+</span> @Zeile</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #0000FF;">RIGHT</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#40;</span>@Zeile&nbsp;&nbsp;,@End_Delim_Len<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&lt;&gt;</span> @Delim_E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Zeile <span style="color: #808080;">=</span> @Zeile <span style="color: #808080;">+</span> @Delim_E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Delimiter erweitern </span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Delim,<span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&lt;&gt;</span> N<span style="color: #FF0000;">'%'</span> <span style="color: #0000FF;">SET</span> @Delim <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'%'</span><span style="color: #808080;">+</span> @Delim</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #0000FF;">RIGHT</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#40;</span>@Delim,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>&nbsp;&nbsp; <span style="color: #808080;">&lt;&gt;</span> N<span style="color: #FF0000;">'%'</span> <span style="color: #0000FF;">SET</span> @Delim <span style="color: #808080;">=</span> @Delim <span style="color: #808080;">+</span> N<span style="color: #FF0000;">'%'</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@End_Delim,<span style="color: #000;">1</span>,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&lt;&gt;</span> N<span style="color: #FF0000;">'%'</span> <span style="color: #0000FF;">SET</span> @End_Delim <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'%'</span><span style="color: #808080;">+</span> @End_Delim</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #0000FF;">RIGHT</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#40;</span>@End_Delim,<span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>&nbsp;&nbsp; <span style="color: #808080;">&lt;&gt;</span> N<span style="color: #FF0000;">'%'</span> <span style="color: #0000FF;">SET</span> @End_Delim <span style="color: #808080;">=</span> @End_Delim <span style="color: #808080;">+</span> N<span style="color: #FF0000;">'%'</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Initial-Position setzen</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Pos&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">=</span> 1</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @TokenCnt&nbsp;&nbsp;<span style="color: #808080;">=</span> 1</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_Pos_S <span style="color: #808080;">=</span> <span style="color: #FF00FF;">PATINDEX</span><span style="color: #808080;">&#40;</span>@Delim,@Zeile<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_Pos_E <span style="color: #808080;">=</span> <span style="color: #FF00FF;">PATINDEX</span><span style="color: #808080;">&#40;</span>@End_Delim,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Zeile,@Delim_Pos_S<span style="color: #808080;">+</span>@Delim_Len ,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datalength<span style="color: #808080;">&#40;</span>@Zeile<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span><span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">+</span> @Delim_Pos_S</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">+</span> @Delim_Len<span style="color: #808080;">-</span><span style="color: #000;">1</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Delimiter und Token suchen</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @TokenNr <span style="color: #808080;">&gt;</span> 0</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">&#40;</span>@Delim_Pos_S <span style="color: #808080;">&gt;</span> 0 and @Delim_Pos_E <span style="color: #808080;">&gt;</span> 0<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Ermittlung des Token ...</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @<span style="color: #FF00FF;">LEN</span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">=</span> @Delim_Pos_E <span style="color: #808080;">-</span> @Delim_Pos_S <span style="color: #808080;">-</span> @Delim_Len</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @RetWert <span style="color: #808080;">=</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Zeile,@Delim_Pos_S <span style="color: #808080;">+</span> @Delim_Len,@<span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Vorbereitung auf den nächsten Token ...</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @TokenCnt <span style="color: #808080;">=</span> @TokenNr <span style="color: #0000FF;">BREAK</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #0000FF;">SET</span> @TokenCnt <span style="color: #808080;">=</span> @TokenCnt <span style="color: #808080;">+</span> <span style="color: #000;">1</span>;</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Zeile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Zeile,@Delim_Pos_E <span style="color: #808080;">+</span> @End_Delim_Len,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datalength<span style="color: #808080;">&#40;</span>@Zeile<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span>2 <span style="color: #808080;">-</span> @Delim_Pos_E<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @Delim_S <span style="color: #808080;">=</span> @Delim_E and datalength<span style="color: #808080;">&#40;</span>@Zeile<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span>2 <span style="color: #808080;">&gt;</span> 0</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Zeile,1,@Delim_Len&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&lt;&gt;</span> @Delim_S</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Zeile <span style="color: #808080;">=</span> @Delim_S <span style="color: #808080;">+</span> @Zeile</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> <span style="color: #0000FF;">RIGHT</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">&#40;</span>@Zeile&nbsp;&nbsp;,@End_Delim_Len<span style="color: #808080;">&#41;</span> <span style="color: #808080;">&lt;&gt;</span> @Delim_E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Zeile <span style="color: #808080;">=</span> @Zeile <span style="color: #808080;">+</span> @Delim_E</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_Pos_S <span style="color: #808080;">=</span> <span style="color: #FF00FF;">PATINDEX</span><span style="color: #808080;">&#40;</span>@Delim,@Zeile<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Delim_Pos_E <span style="color: #808080;">=</span> <span style="color: #FF00FF;">PATINDEX</span><span style="color: #808080;">&#40;</span>@End_Delim,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #FF00FF;">SUBSTRING</span><span style="color: #808080;">&#40;</span>@Zeile,@Delim_Pos_S<span style="color: #808080;">+</span>@Delim_Len,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datalength<span style="color: #808080;">&#40;</span>@Zeile<span style="color: #808080;">&#41;</span><span style="color: #808080;">/</span>2<span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">+</span> @Delim_Pos_S</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #808080;">+</span> @Delim_Len<span style="color: #808080;">-</span>1</li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">IF</span> @Delim_Pos_E <span style="color: #808080;">&lt;=</span> @Delim_Len <span style="color: #0000FF;">SET</span> @RetWert <span style="color: #808080;">=</span> <span style="color: #808080;">NULL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- Returncodes setzen</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @RetWert <span style="color: #808080;">=</span> <span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> @TokenCnt <span style="color: #808080;">&lt;</span>&nbsp;&nbsp;@TokenNr	<span style="color: #0000FF;">THEN</span> <span style="color: #808080;">NULL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">WHEN</span> @TokenNr&nbsp;&nbsp;<span style="color: #808080;">&lt;</span>&nbsp;&nbsp;0			<span style="color: #0000FF;">THEN</span> <span style="color: #808080;">NULL</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">WHEN</span> @TokenNr&nbsp;&nbsp;<span style="color: #808080;">=</span>&nbsp;&nbsp;0			<span style="color: #0000FF;">THEN</span> @Line</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">ELSE</span> @RetWert</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">RETURN</span> @RetWert</li><li><span style="color: #0000FF;">END</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p>Tip: Man kann die Funktionsaufrufe natürlich auch ineinander verschachteln!</p>
<p>have fun</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/5C74VI8LUtc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=932</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=932</feedburner:origLink></item>
		<item>
		<title>T-SQL CASE und die implizite Datentypkonvertierung</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/I41I6c8yqCg/</link>
		<comments>http://www.kronester.com/?p=920#comments</comments>
		<pubDate>Wed, 23 Sep 2009 09:33:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[case]]></category>
		<category><![CDATA[datentypkonvertierung]]></category>
		<category><![CDATA[implied]]></category>
		<category><![CDATA[implizit]]></category>
		<category><![CDATA[Sql Server]]></category>
		<category><![CDATA[T-Sql]]></category>
		<category><![CDATA[Tsql]]></category>
		<category><![CDATA[typ konvertierung]]></category>
		<category><![CDATA[type cast]]></category>

		<guid isPermaLink="false">http://www.kroni.de/?p=920</guid>
		<description><![CDATA[Wenn man in einem Ausdruck einen CASE-Block verwendet, so ist dies auf den ersten Blick noch keine Besonderheit. Vergisst man jedoch dabei, dass SQL Server eine implizite Datentypkonvertierung vornimmt, so kann dies zu fehlerhaften Ergebnissen führen die noch dazu sehr schwer zu finden sind.
Betrachten wir hierfür einmal folgendes Beispiel:

declare @AlteKndNr varchar(15)
declare @Von    [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-70">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-70');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-70");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p>Wenn man in einem Ausdruck einen CASE-Block verwendet, so ist dies auf den ersten Blick noch keine Besonderheit. Vergisst man jedoch dabei, dass SQL Server eine implizite Datentypkonvertierung vornimmt, so kann dies zu fehlerhaften Ergebnissen führen die noch dazu sehr schwer zu finden sind.</p>
<p>Betrachten wir hierfür einmal folgendes Beispiel:</p>
<p>
<!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">DECLARE</span> @AlteKndNr <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>15<span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @Von&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>15<span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @Auf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span>15<span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @Regel&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000FF;">INT</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @AlteKndNr <span style="color: #808080;">=</span> <span style="color: #FF0000;">'K011110999-VIP'</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @Regel <span style="color: #808080;">=</span> 1</li><li><span style="color: #0000FF;">SET</span> @Von&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #0000FF;">CASE</span> @Regel <span style="color: #0000FF;">WHEN</span> 1 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'099'</span> <span style="color: #0000FF;">WHEN</span> 2 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'0111'</span> <span style="color: #0000FF;">ELSE</span> 0 <span style="color: #0000FF;">END</span></li><li><span style="color: #0000FF;">SET</span> @Auf&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #0000FF;">CASE</span> @Regel <span style="color: #0000FF;">WHEN</span> 1 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'033'</span> <span style="color: #0000FF;">WHEN</span> 2 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'0000'</span> <span style="color: #0000FF;">ELSE</span> 0 <span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SELECT</span> NeueKndNr <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@AlteKndNr, @Von, @Auf<span style="color: #808080;">&#41;</span>, @Von, @Auf</li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @Regel <span style="color: #808080;">=</span> 2</li><li><span style="color: #0000FF;">SET</span> @Von&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #0000FF;">CASE</span> @Regel <span style="color: #0000FF;">WHEN</span> 1 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'099'</span> <span style="color: #0000FF;">WHEN</span> 2 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'0111'</span> <span style="color: #0000FF;">ELSE</span> 0 <span style="color: #0000FF;">END</span></li><li><span style="color: #0000FF;">SET</span> @Auf&nbsp;&nbsp; <span style="color: #808080;">=</span> <span style="color: #0000FF;">CASE</span> @Regel <span style="color: #0000FF;">WHEN</span> 1 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'033'</span> <span style="color: #0000FF;">WHEN</span> 2 <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'0000'</span> <span style="color: #0000FF;">ELSE</span> 0 <span style="color: #0000FF;">END</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SELECT</span> NeueKndNr <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@AlteKndNr, @Von, @Auf<span style="color: #808080;">&#41;</span>, @Von, @Auf</li><li>&nbsp;</li><li><span style="color: #008080;">-- -------------------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Ergebnisse:</span></li><li><span style="color: #008080;">--</span></li><li><span style="color: #008080;">-- NeueKdNr bei @Regel = 1: K011110339-VIP = OK</span></li><li><span style="color: #008080;">-- NeueKdNr bei @Regel = 2: K0010999-VIP&nbsp;&nbsp; = FALSCH</span></li><li><span style="color: #008080;">--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K000010999-VIP = Das währe richtig!</span></li><li><span style="color: #008080;">-- -------------------------------------------------------------------------</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p><span id="more-920"></span>Wie man sehen kann wird bei @Regel=2 eine falsche Konvertierung durchgeführt. Dies liegt an der oben besprochenen impliziten Konvertierungsregel von SQL Server. Wenn mehrere Datentypen in einem Ausdruck vorkommen so werden diese in einen Zieldatentyp konvertiert.</p>
<p>Der Typ des Zieldatentyps ist der Typ des Wertes der in folgender Tabelle den höchsten Prioritätswert (1) aufweist.</p>
<p>In unserem Fall wird im CASE-Block in den When-Zweigen ein String zurückgegeben, im Else-Zweig hingegen ein Integerwert! Obwohl der Else-Zweig nicht angesprochen wird, ist der Gesamtdatentyp des CASE-Blocks gem. Konvertierungstabelle ein Integerwert, da dieser die höhere Priorität gegenüber den varchar-Werten der When-Zweige aufweist.</p>
<p>Wenn man also den Else-Zweig des Case-Blocks mit <strong>Else &#8216;0&#8242;</strong> definiert (man beachte die Hochkommas), dann wird auch das richtige Ergebnis ausgegeben.</p>
<p>Hier die Tabelle die die Prioritäten bei der impliziten Typkonvertierung aufzeigt:</p>
<table style="text-align: center;" border="0">
<caption><span style="font-size: medium;"><strong>Datentyp-Prioritäten</strong></span></caption>
<tbody>
<tr>
<td><strong>Priorität</strong></td>
<td><strong>Datentyp</strong></td>
</tr>
<tr>
<td>1</td>
<td>Benuter-Definierter Typ</td>
</tr>
<tr>
<td>2</td>
<td>sql_variant</td>
</tr>
<tr>
<td>3</td>
<td>xml</td>
</tr>
<tr>
<td>4</td>
<td>datetime</td>
</tr>
<tr>
<td>5</td>
<td>smalldatetime</td>
</tr>
<tr>
<td>6</td>
<td>float</td>
</tr>
<tr>
<td>7</td>
<td>real</td>
</tr>
<tr>
<td>8</td>
<td>decimal</td>
</tr>
<tr>
<td>9</td>
<td>money</td>
</tr>
<tr>
<td>10</td>
<td>smallmoney</td>
</tr>
<tr>
<td>11</td>
<td>bigint</td>
</tr>
<tr>
<td>12</td>
<td>int</td>
</tr>
<tr>
<td>13</td>
<td>smallint</td>
</tr>
<tr>
<td>14</td>
<td>tinyint</td>
</tr>
<tr>
<td>15</td>
<td>bit</td>
</tr>
<tr>
<td>16</td>
<td>ntext</td>
</tr>
<tr>
<td>17</td>
<td>text</td>
</tr>
<tr>
<td>18</td>
<td>image</td>
</tr>
<tr>
<td>19</td>
<td>timestamp</td>
</tr>
<tr>
<td>20</td>
<td>uniqueidentifier</td>
</tr>
<tr>
<td>21</td>
<td>nvarchar</td>
</tr>
<tr>
<td>22</td>
<td>nchar</td>
</tr>
<tr>
<td>23</td>
<td>varchar</td>
</tr>
<tr>
<td>24</td>
<td>char</td>
</tr>
<tr>
<td>25</td>
<td>varbinary</td>
</tr>
<tr>
<td>26</td>
<td>binary</td>
</tr>
</tbody>
</table>
<p>have fun <img src='http://www.kronester.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/I41I6c8yqCg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=920</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=920</feedburner:origLink></item>
		<item>
		<title>‘virtuelle’ Arrays mit T-SQL</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/GoU5fTiygQY/</link>
		<comments>http://www.kronester.com/?p=909#comments</comments>
		<pubDate>Tue, 22 Sep 2009 09:33:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>
		<category><![CDATA[charindex]]></category>
		<category><![CDATA[Delimiter]]></category>
		<category><![CDATA[dynamic sql]]></category>
		<category><![CDATA[dynamisches sql]]></category>
		<category><![CDATA[Nvarchar]]></category>
		<category><![CDATA[Sql Server]]></category>
		<category><![CDATA[Tsql]]></category>
		<category><![CDATA[virtual array]]></category>
		<category><![CDATA[virtuelle arrays]]></category>

		<guid isPermaLink="false">http://www.kroni.de/?p=909</guid>
		<description><![CDATA[In T-SQL sind per Definition keine Arrays vorgesehen. Es gibt jedoch Fälle in denen der Einsatz eines Arrays von Vorteil wäre.
In einem konkreten Fall soll eine Prozedur einen Datenwert als Parameter erhalten. Dieser Wert wird jedoch in den, für die Abfrage zugrundeliegenden Tabellen nicht direkt verwendet. Vielmehr wird auf den Parameterwert nur indirekt über den [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-85">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-85');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-85");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p>In T-SQL sind per Definition keine Arrays vorgesehen. Es gibt jedoch Fälle in denen der Einsatz eines Arrays von Vorteil wäre.</p>
<p>In einem konkreten Fall soll eine Prozedur einen Datenwert als Parameter erhalten. Dieser Wert wird jedoch in den, für die Abfrage zugrundeliegenden Tabellen nicht direkt verwendet. Vielmehr wird auf den Parameterwert nur indirekt über den Primärschlüssel (IdentityFeld) der Schlüsseltabelle verwiesen.</p>
<p>In der Prozedur müsste jetzt eine Abfrage in der Form:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&lt;</span>feldliste<span style="color: #808080;">&gt;</span></li><li><span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&lt;</span>komplexe Abfrage<span style="color: #808080;">&gt;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;join Schlüsseltabelle <span style="color: #0000FF;">ON</span> Code <span style="color: #808080;">=</span></li><li><span style="color: #808080;">&lt;</span>parameterwert<span style="color: #808080;">&gt;</span></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p>erstellt werden.</p>
<p>Grundsätzlich ist dagegen ja nichts einzuwenden. Wenn der Join gegen die Schlüsseltabelle jedoch die Laufzeit des Gesamtstatements spürbar verlängert und zusätzlich in der Prozedur dieser Join mehrfach verwendet wird, dann sollte man darüber nachdenken ob es vielleicht eine performantere Lösung gibt.</p>
<p>Da es kein Array in T-SQL gibt kann man dieses als String simulieren. Dieses virtuelle Array trennt die einzelnen Werte durch einen definierten Delimiter (in meinem Fall &#8216;|&#8217; der senkrechte Strich). Bei der Abfrage muss jetzt nur der Abfragewert in einen String mit umgebenden Delimitern convertiert werden und über CHARINDEX mit der virtuellen Array-Variablen verglichen werden.</p>
<p>Eine Lösung könnte damit in etwa so aussehen:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #808080;">&lt;</span>erstelle <span style="color: #0000FF;">ARRAY</span> mit IdentWerten die durch parameterwert definiert sind<span style="color: #808080;">&gt;</span></li><li><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">&lt;</span>feldliste<span style="color: #808080;">&gt;</span></li><li><span style="color: #0000FF;">FROM</span> <span style="color: #808080;">&lt;</span>komplexe Abfrage<span style="color: #808080;">&gt;</span></li><li><span style="color: #0000FF;">WHERE</span> <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'|'</span><span style="color: #808080;">+</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>,<span style="color: #808080;">&lt;</span>quellfeld<span style="color: #808080;">&gt;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">+</span><span style="color: #FF0000;">'|'</span>,@<span style="color: #0000FF;">ARRAY</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> <span style="color: #000;">0</span></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<p><span id="more-909"></span></p>
<p>Ein Beispiel&nbsp;hierfür&nbsp;findet man&nbsp;in nachfolgenden Script:</p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span> </li><li>&nbsp;</li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Script in Variable @Cmd erstellt Array-String</span></li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">DECLARE</span> @Cmd <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;use &lt;@Datenbank&gt;</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;declare @Feld&nbsp;&nbsp; nvarchar(1000)</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;declare @Result nvarchar(max)</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;declare @Delim&nbsp;&nbsp;nvarchar(10)</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;set @Delim = '</span><span style="color: #FF0000;">'|'</span><span style="color: #FF0000;">'</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;set @Result = @Delim</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;declare FieldListCur cursor for</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;select &lt;@QuellFeld&gt; from &lt;@Quelltabelle&gt; where &lt;@Where&gt;</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;open FieldListCur</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;fetch next from FieldListCur into @Feld</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;while @@fetch_status = 0</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;begin</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set @Result = @Result + @Feld + @Delim</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fetch next from FieldListCur into @Feld</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;end</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;close FieldListCur</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;deallocate FieldListCur</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;select @Result as Result</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;'</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Script konfigurieren</span></li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Cmd,<span style="color: #FF0000;">'&lt;@Datenbank&gt;'</span>,<span style="color: #FF0000;">'AdventureWorks'</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Cmd,<span style="color: #FF0000;">'&lt;@QuellFeld&gt;'</span>,<span style="color: #FF0000;">'ContactID'</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Cmd,<span style="color: #FF0000;">'&lt;@Quelltabelle&gt;'</span>,<span style="color: #FF0000;">'Person.Contact'</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Cmd,<span style="color: #FF0000;">'&lt;@Where&gt;'</span>,<span style="color: #FF0000;">'FirstName like '</span><span style="color: #FF0000;">'Fernan%'</span><span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Script ausführen und Ergebnis in Variable @Array schreiben</span></li><li><span style="color: #008080;">-- Die @Tabelle wird nur zur temporäran Übernahme des Ergebnisses benötigt.</span></li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">ARRAY</span> <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @TArray <span style="color: #0000FF;">TABLE</span> <span style="color: #808080;">&#40;</span>wert <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @TArray <span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">SP_EXECUTESQL</span> @Cmd</li><li>&nbsp;</li><li><span style="color: #0000FF;">SELECT</span> @<span style="color: #0000FF;">ARRAY</span> <span style="color: #808080;">=</span> wert <span style="color: #0000FF;">FROM</span> @TArray</li><li>&nbsp;</li><li><span style="color: #0000FF;">DELETE</span> @TArray</li><li>&nbsp;</li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li><span style="color: #008080;">-- Anwendungsbeispiel:</span></li><li><span style="color: #008080;">-- Auslesen von Datensätzen die eine ContactID haben die in</span></li><li><span style="color: #008080;">-- unserem Array enthalten ist.</span></li><li><span style="color: #008080;">-- -----------------------------------------------------------------</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">SELECT</span> <span style="color: #808080;">*</span></li><li><span style="color: #0000FF;">FROM</span> AdventureWorks.<span style="color: #202020;">Person</span>.<span style="color: #202020;">Contact</span></li><li><span style="color: #0000FF;">WHERE</span> <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'|'</span><span style="color: #808080;">+</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">VARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span>,ContactID<span style="color: #808080;">&#41;</span><span style="color: #808080;">+</span><span style="color: #FF0000;">'|'</span>,@<span style="color: #0000FF;">ARRAY</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&gt;</span> <span style="color: #000;">0</span></li><li></li></ol></div></pre><!--END_DEVFMTCODE-->
</p>
<blockquote><p><strong>Hinweis:</strong> Wer Fragen zu den Beispielen bzw. Themen an mich hat soll doch bitte über die Kommentarfunktion am&nbsp;Ende jedes Artikels seine Fragen&nbsp;einstellen. Direkte Mails&nbsp;gehen zwar auch, jedoch können andere in einem solchen Fall nicht an den Ergebnissen bzw. Verbesserungen teilhaben.</p>
</blockquote>
<p> <img src='http://www.kronester.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Viel Spaß beim ausprobieren</p>
<p> <img src='http://www.kronester.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &nbsp;</p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/GoU5fTiygQY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=909</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=909</feedburner:origLink></item>
		<item>
		<title>Datensatzlänge einer Abfrage schätzen</title>
		<link>http://feedproxy.google.com/~r/FourDragons/~3/9F-qF0iB7YA/</link>
		<comments>http://www.kronester.com/?p=881#comments</comments>
		<pubDate>Tue, 08 Sep 2009 16:16:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[SQL-Server 2005]]></category>

		<guid isPermaLink="false">http://www.kroni.de/?p=881</guid>
		<description><![CDATA[

Gerade wenn man ein bestehendes Datenbanksystem optimieren möchte, könnte die Frage nach der durchschnittlichen Breite einer Abfrage auftauchen. Speziell wenn man keine Tabelle zur Hand hat die in ihren Properties zumindest den verbrauchten Speicherplatz anzeigt, ist die nachfolgende Prozedur vielleicht ganz nützlich.

Es werden für eine gegebene Abfrage die Ergebnisse in eine temporäre Tabelle geschrieben und [...]]]></description>
			<content:encoded><![CDATA[<div class="fdrag_phi_JustPrint" style="display:none; border: 1px solid red; padding:1em; margin-top:20px;">
<p><center><small><b>Achtung &#8211; Urheberrechtshinweis!</b></center></p>
<p>Die Artikel dieses Blogs stehen unter einer <strong>CREATIVE COMMONS LICENSE</strong>! Bitte beachten Sie die entsprechenden Hinweise auf http://creativecommons.org/licenses/by-sa/2.0/de/
<p>Bei Fragen oder Anregungen wenden Sie sich bitte an <strong><span id="emob-oybt@sbheqentbaf.qr-38">blog {at} fourdragons(.)de</span><script type="text/javascript">
    var mailNode = document.getElementById('emob-oybt@sbheqentbaf.qr-38');
    var linkNode = document.createElement('a');
    linkNode.setAttribute('href', "mailto:%62%6C%6F%67%40%66%6F%75%72%64%72%61%67%6F%6E%73%2E%64%65");
    tNode = document.createTextNode("blog {at} fourdragons(.)de");
    linkNode.appendChild(tNode);
    linkNode.setAttribute('id', "emob-oybt@sbheqentbaf.qr-38");
    mailNode.parentNode.replaceChild(linkNode, mailNode);
</script></strong></p>
</p>
</div>
<p><!--wp_fromhtmlpreview_devfmt--></p>
<p>Gerade wenn man ein bestehendes Datenbanksystem optimieren möchte, könnte die Frage nach der durchschnittlichen Breite einer Abfrage auftauchen. Speziell wenn man keine Tabelle zur Hand hat die in ihren Properties zumindest den verbrauchten Speicherplatz anzeigt, ist die nachfolgende Prozedur vielleicht ganz nützlich.</p>
<p>Es werden für eine gegebene Abfrage die Ergebnisse in eine temporäre Tabelle geschrieben und dann mittels der Funktion DATALENGTH die tatsächliche Länge eines Feldes bestimmt. Die durchschnittliche Summe der Gesamtlänge eines Datensatzes wird in der Rückgabe angezeigt.</p>
<p>Wenn man diese Durchschnittslänge mit der Anzahl der Datensätze multipliziert, erhält man den Nettowert des Datenvolumens das transferiert wird. (zumindest annähernd;))</p>
<p>Wenn ein Feld einen NULL-Wert enthält, setzt die Prozedur eine Feldlänge von 4 Byte ein. Dies wird als Mittelwert einer leeren Feldlänge verwendet und könnte in einer weiteren Ausbaustufe ggf. noch aus den System-Views für die Feldtypen genauer bestimmt werden.</p>
<p><br class="spacer_" /></p>
<p>Die Abfrage sollte eine repräsentative Menge an Daten zurückliefern. Es ist vor allem bei sehr großen Ergebnismengen ein wenig Vorsicht angesagt, um nicht die Temp-Datenbank in Bedrängnis geraten zu lassen <img src='http://www.kronester.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><span id="more-881"></span></p>
<p><!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> dbo.<span style="color: #202020;">GetAvgRecordWidth</span></li><li>&nbsp;&nbsp;@Datenbank sysname</li><li>, @SourceCmd <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">AS</span></li><li><span style="color: #0000FF;">BEGIN</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @TempName <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span>1000<span style="color: #808080;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @IntoTemp <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span>1000<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @TempName <span style="color: #808080;">=</span> <span style="color: #FF0000;">'##TempCntSource_'</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>newid<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>,<span style="color: #FF0000;">'-'</span>,<span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @IntoTemp <span style="color: #808080;">=</span> <span style="color: #FF0000;">' into '</span> <span style="color: #808080;">+</span> @TempName <span style="color: #808080;">+</span> <span style="color: #FF0000;">' FROM '</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @SourceCmd <span style="color: #808080;">=</span> <span style="color: #FF00FF;">STUFF</span><span style="color: #808080;">&#40;</span>@SourceCmd,<span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'from'</span>,<span style="color: #FF00FF;">LOWER</span><span style="color: #808080;">&#40;</span>@SourceCmd<span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>,<span style="color: #000;">4</span>,@IntoTemp<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080;">-- ---------------------------------------------------------------------------</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">DECLARE</span> @Cmd <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> <span style="color: #FF0000;">'USE '</span> <span style="color: #808080;">+</span> @Datenbank <span style="color: #808080;">+</span> <span style="color: #FF0000;">'; '</span> <span style="color: #808080;">+</span> @SourceCmd <span style="color: #808080;">+</span> N<span style="color: #FF0000;">'</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;declare&nbsp;&nbsp;@SQL nvarchar(max)</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,@Feld sysname</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,@Delim varchar(100)</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;set @Delim = N'</span><span style="color: #FF0000;">'Select avg('</span><span style="color: #FF0000;">'</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;set @SQL&nbsp;&nbsp; = N'</span><span style="color: #FF0000;">''</span><span style="color: #FF0000;">'</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;declare Colcur cursor for</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;select c.name</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;from tempdb.sys.objects o</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;join tempdb.sys.columns c on c.object_id = o.object_id</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;where o.name like '</span><span style="color: #FF0000;">'&lt;##TempCntSource&gt;%'</span><span style="color: #FF0000;">'</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;open Colcur</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;fetch next from&nbsp;&nbsp;Colcur into @Feld</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;while @@fetch_status = 0</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;begin</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set @SQL = @SQL + @Delim + '</span><span style="color: #FF0000;">'isnull(DATALENGTH('</span><span style="color: #FF0000;">' + @Feld + '</span><span style="color: #FF0000;">'),4)'</span><span style="color: #FF0000;">'</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set @Delim = '</span><span style="color: #FF0000;">'+'</span><span style="color: #FF0000;">'</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fetch next from&nbsp;&nbsp;Colcur into @Feld</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;end</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;close Colcur</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;deallocate Colcur</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;&nbsp;@SQL = @SQL + '</span><span style="color: #FF0000;">') from &lt;##TempCntSource&gt;'</span><span style="color: #FF0000;">'</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;exec sp_executesql @SQL</span></li><li>&nbsp;</li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;drop table &lt;##TempCntSource&gt;</span></li><li><span style="color: #FF0000;">&nbsp;&nbsp;&nbsp;&nbsp;'</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">SET</span> @Cmd <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>@Cmd,<span style="color: #FF0000;">'&lt;##TempCntSource&gt;'</span>,@TempName<span style="color: #808080;">&#41;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">SP_EXECUTESQL</span> @Cmd</li><li><span style="color: #0000FF;">END</span></li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>Der Aufruf sieht dann wie folgt aus:<br />
<!--DEVFMTCODE--><pre class="devcodeblock" title="T-SQL"><div class="devcodeoverflow"><ol><li><span style="color: #0000FF;">DECLARE</span> @Stmt <span style="color: #0000FF;">NVARCHAR</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#41;</span></li><li><span style="color: #0000FF;">DECLARE</span> @Datenbank sysname</li><li>&nbsp;</li><li><span style="color: #0000FF;">SET</span> @Datenbank <span style="color: #808080;">=</span> N<span style="color: #FF0000;">'AdventureWorks'</span></li><li><span style="color: #0000FF;">SET</span> @Stmt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #808080;">=</span> N<span style="color: #FF0000;">'select * from HumanResources.Employee'</span></li><li>&nbsp;</li><li><span style="color: #0000FF;">EXEC</span> dbo.<span style="color: #202020;">GetAvgRecordWidth</span> @Datenbank,@Stmt</li></ol></div></pre><!--END_DEVFMTCODE--></p>
<p>have fun <img src='http://www.kronester.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  <br class="spacer_" /></p>
<img src="http://feeds.feedburner.com/~r/FourDragons/~4/9F-qF0iB7YA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.kronester.com/?feed=rss2&amp;p=881</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.kronester.com/?p=881</feedburner:origLink></item>
	</channel>
</rss>
