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

<channel>
	<title>ixto-Blog &#187; SQL Server 2005</title>
	<atom:link href="http://www.ixto.de/blog/category/sql-server-2005/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ixto.de/blog</link>
	<description>Business Intelligence, Database Consulting, Software Development</description>
	<lastBuildDate>Mon, 26 Sep 2011 09:23:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Pr&#252;fung auf Nachkommastellen bei Importen (SSIS)</title>
		<link>http://www.ixto.de/blog/allgemein/prfung-auf-nachkommastellen-bei-importen-ssis/</link>
		<comments>http://www.ixto.de/blog/allgemein/prfung-auf-nachkommastellen-bei-importen-ssis/#comments</comments>
		<pubDate>Mon, 30 May 2011 16:07:57 +0000</pubDate>
		<dc:creator>Ricardo Radke</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Integration Services 2005]]></category>
		<category><![CDATA[Integration Services 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=549</guid>
		<description><![CDATA[Es gibt Mittel und Wege, Gültigkeitsprüfungen für Gleitkommazahlen innerhalb der Integration Services zu realisieren. Die Überlegungen zum Vorgehen können dabei von einfachen Konvertierungen bis hin zu komplexen Script-Tasks reichen.    

In diesem Beitrag möchte ich eine Möglichkeit erläutern, die so simpel ist, dass der ein oder andere vielleicht gar nicht erst daran gedacht [...]]]></description>
			<content:encoded><![CDATA[<p>Es gibt Mittel und Wege, Gültigkeitsprüfungen für Gleitkommazahlen innerhalb der Integration Services zu realisieren. Die Überlegungen zum Vorgehen können dabei von einfachen Konvertierungen bis hin zu komplexen Script-Tasks reichen.    </p>
<p></br>
<p>In diesem Beitrag möchte ich eine Möglichkeit erläutern, die so simpel ist, dass der ein oder andere vielleicht gar nicht erst daran gedacht hat – frei nach dem Motto: „Ich seh‘ den Wald vor lauter Bäumen nicht“.    </p>
<p> <span id="more-549"></span> <br /></br>  Nehmen wir an, es handelt sich bei unserer Zahl um einen Prozentwert, dessen Anzahl der Nachkommastellen wir auf 5 begrenzen und im Falle der Überschreitung einen Fehler ausgeben lassen wollen (z.B. wenn die Zielspalte in der Datenbank nicht mehr als 5 zulässt). Dies würde sich zwar mit einfachen Mitteln realisieren lassen, jedoch unter Umständen nicht immer zum gewünschten Ergebnis führen.    </p>
<p></br>Angenommen es handelt sich um den Wert <i>12,12345<b>00 </b></i>– so würden die beiden letzten Nachkommastellen nach „Schema-F“ abgeschnitten und ein Fehler erzeugt werden. Da es sich in diesem Falle aber um das Abschneiden von lediglich zwei nullen handelt und somit der numerische Wert trotzdem unverändert und somit gültig bleibt, muss hier eine andere Lösung her.     </p>
<p></br>
<p>Wie? Ganz einfach! Man vergleiche die Zahl mit sich selbst – und zwar konvertiert in einen Gleitkommawert mit 5, sowie mit 6 Nachkommastellen. Das ganze könnte dann z.B. so aussehen:    </p>
<p></br><i>(DT_NUMERIC, 10, 5)Wert == (DT_NUMERIC, 10, 6)Wert      <br /></i></p>
<p></br>
<p>Die folgende Abbildung sollte das Prinzip noch einmal veranschaulichen und weitere Erläuterungen überflüssig machen <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smiley" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/Prfung-auf-Nachkommastellen-bei-Importen_FE03/wlEmoticon-smile.png" />     </p>
<p></br><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/Prfung-auf-Nachkommastellen-bei-Importen_FE03/ssis_conversion.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ssis_conversion" border="0" alt="ssis_conversion" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/Prfung-auf-Nachkommastellen-bei-Importen_FE03/ssis_conversion_thumb.png" width="494" height="263" /></a></p>
<p></br></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/allgemein/prfung-auf-nachkommastellen-bei-importen-ssis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSIS 2005 Suche-Task &#8211; Wo ist meine Spalte?</title>
		<link>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/ssis-2005-suche-task-wo-ist-meine-spalte/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/ssis-2005-suche-task-wo-ist-meine-spalte/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 09:12:00 +0000</pubDate>
		<dc:creator>Martin Ihrke</dc:creator>
				<category><![CDATA[Integration Services 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=531</guid>
		<description><![CDATA[Wenn kleine Buchstaben groß sein sollten…
Es gibt Bugs, die sind, wenn man sie denn kennt und zu umschiffen weiß, eher amüsant als ärgerlich. Zumeist sind sie längst bekannt und zaubern ein Lächeln ins Gesicht des Eingeweihten, wenn er diesem beim Entwickeln einmal mehr begegnet. Und doch kann es passieren, dass sich ein solcher Bug eben [...]]]></description>
			<content:encoded><![CDATA[<p>Wenn kleine Buchstaben groß sein sollten…</p>
<p>Es gibt Bugs, die sind, wenn man sie denn kennt und zu umschiffen weiß, eher amüsant als ärgerlich. Zumeist sind sie längst bekannt und zaubern ein Lächeln ins Gesicht des Eingeweihten, wenn er diesem beim Entwickeln einmal mehr begegnet. Und doch kann es passieren, dass sich ein solcher Bug eben doch nicht überall herumgesprochen hat, was dann oftmals zu Unmut und Verwirrung führt.</p>
<p><span id="more-531"></span></p>
<p>Ein Klassiker dieser Art ist der Suche-Task der Integration Services 2005 in deutscher Sprachversion. Dieser birgt nämlich einen gemeinen Fallstrick, der oft zu wirren ETL-Paketen führt, wenn man auch nur einen einzigen Mausklick vergisst. Der Sachverhalt ist folgender: Nach erfolgter Definition der Spalten-Zuordnungen für die Übereinstimmungsbedingungen und Auswahl der entsprechenden Spalten in der Verweistabelle vergisst der Task anscheinend seine Konfiguration der Spalten, nachdem man die Einstellungen mit OK bestätigt und sich der Dialog schließt. Konkret könnte das Ganze ungefähr so ausschauen:<br />
<a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image002.jpg"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="clip_image002" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image002_thumb.jpg" border="0" alt="clip_image002" width="223" height="244" /></a></p>
<p>Nach dem Bestätigen verschwindet aber die eben neu hinzugefügte Spalten wie von Geisterhand wieder:</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image004.jpg"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="clip_image004" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image004_thumb.jpg" border="0" alt="clip_image004" width="244" height="233" /></a></p>
<p>Auch nach erneutem Öffnen des Konfigurationsdialogs hat es den Anschein, als wäre hier niemals etwas eingestellt worden. Die eingangs erwähnten wirren ETL-Pakete entstehen nun durch den Workaround, dass man eine oder mehrere Spalten vorher angelegt, etwas durch den Abgeleitete Spalte-Task, und in der Suche diese mit dem nachgeschlagenen Wert überschreibt. Dies funktioniert nämlich anstandslos.</p>
<p>Dabei gibt es einen viel effektiveren Weg, an seine Nachschlage-Spalten zu kommen: ein Mausklick an der richtigen Stelle im Konfigurationsdialog. Der entscheidende Punkt ist nämlich die Dropdown-Box „Suchvorgang“. Der aufmerksame Entwickler sieht den Unterschied: Hier gibt es die Option „Als neue Spalte hinzufügen“ mit einem großen A an erster Stelle. Die Standard-Auswahl beginnt mit einem kleinen A:</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image006.jpg"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="clip_image006" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image006_thumb.jpg" border="0" alt="clip_image006" width="223" height="244" /></a></p>
<p>Und dies ist auch schon des Rätsels Lösung: wenn man sich nun die einzig auswählbare Option entscheidet, klappt es mit der neuen Spalte ohne Probleme. Offensichtlich haben die Integration Services hier Probleme mit den angebotenen Optionen dieses Dialogs und der erlaubten Auswahl. Ein Blick auf die Metadaten beweist: die neue Spalte ist tatsächlich vorhanden:</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image008.jpg"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="clip_image008" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/d5a1a692fe72_9D69/clip_image008_thumb.jpg" border="0" alt="clip_image008" width="244" height="216" /></a></p>
<p>Wohlgemerkt betrifft dies unseres Wissens nur SSIS 2005 in deutscher Sprache und könnte durch den ein oder anderen Patch in einigen Versionen auch behoben worden sein. Nichtsdestotrotz begegnen wir immernoch regelmäßig der kritischen Version und auch unter den Entwicklern hat sich das vorgestellte vorgehen noch nicht bis in die hintersten Ecken herumgesprochen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/ssis-2005-suche-task-wo-ist-meine-spalte/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jahreswerte auf Monate verlustfrei verteilen &#8211; Teil 1</title>
		<link>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/jahreswerte-auf-monate-verlustfrei-verteilen-teil-1/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/jahreswerte-auf-monate-verlustfrei-verteilen-teil-1/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 09:15:00 +0000</pubDate>
		<dc:creator>Chris Jacob</dc:creator>
				<category><![CDATA[Integration Services 2005]]></category>
		<category><![CDATA[Integration Services 2008]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=510</guid>
		<description><![CDATA[Ich habe wieder ein schönes Beispiel gefunden an der man die Flexibilität der Integration Services demonstrieren kann. Die Aufgabe ist recht einfach: es geht darum, einen Jahreswert mit Dezimalstellen (in unserem Fall ein numeric(6,2), z.B. ein Euro-Wert) gleichmäßig auf 12 Monate zu verteilen. Die Division sollte uns hoffentlich keine Kopfschmerzen bereiten, die Herausforderung liegt darin, [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe wieder ein schönes Beispiel gefunden an der man die Flexibilität der Integration Services demonstrieren kann. Die Aufgabe ist recht einfach: es geht darum, einen Jahreswert mit Dezimalstellen (in unserem Fall ein numeric(6,2), z.B. ein Euro-Wert) gleichmäßig auf 12 Monate zu verteilen. Die Division sollte uns hoffentlich keine Kopfschmerzen bereiten, die Herausforderung liegt darin, dass unser Datentyp nur zwei Nachkommastellen erlaubt und daher viele Werte bei der Division einen Genauigkeitsverlust erleiden würden.<br />
<span id="more-510"></span><br />
Ein kurzes Beispiel: teilen wir den Wert 100,00 € durch 12 erhalten wir pro Monat einen Wert von 8,3333. € Würden wir nun 12 mal den Wert 8,33 € als Monatswert in unsere Datenbank übernehmen, würden uns über das Jahr hinweg gesehen 0,04 € fehlen. Das Ziel wäre hier, diese 4 Eurocent (also den Differenzbetrag) auf den letzten Monat aufzuschlagen.</p>
<p>&#160;</p>
<p>Das Problem begegnet uns immer dann, wenn in der Datenbank Werte in einer anderen Granularität gespeichert werden (in diesem Fall monatsgenau) als diese von der darauf aufsetzenden Anwendung geliefert werden (diese erlaubt nur jahresgenaue Werte). Für spätere Auswertungen oder Änderungen möchten wir monatsgenaue Werte speichern, ohne den korrekten Jahreswert (die Summe der 12 Monate) zu verlieren.</p>
<p>&#160;</p>
<p>Auch hier führen wieder viele Wege nach Rom, daher zeige ich im ersten Teil neben der eigentlichen Problemstellung und dem Kern der Lösung eine von vier (!) Möglichkeiten die ich gefunden habe um die Aufgabe zu lösen.</p>
<p>&#160;</p>
<p>Zunächst einmal überlege ich mir geeignete Ausdrücke um die oben genannte Anforderung innerhalb eines SSIS-Datenfluss&#8217; umsetzen zu können. Für die Monate 1 bis 11 genügt folgender Ausdruck:</p>
<p>&#160;</p>
<p><font face="Consolas">(DT_NUMERIC,6,2)(Value / 12)</font></p>
<p>&#160;</p>
<p>Der Monat 12 erfordert eine Sonderbehandlung, welche durch folgenden Ausdruck gewährleistet wird:</p>
<p>&#160;</p>
<p><font face="Consolas">(DT_NUMERIC,6,2)(Value &#8211; (DT_NUMERIC,6,2)(11 * (DT_NUMERIC,6,2)(Value / 12)))</font></p>
<p>&#160;</p>
<p>Im Grunde ermittelt dieser Ausdruck die Differenz zwischen dem Jahreswert und der Summe der 11 Monatswerte um den Wert für Monat 12 zu berechnen. Beachten Sie dabei, dass es egal ist ob bei der Ermittlung der Monatswerte ab- oder aufgerundet oder gar abgeschnitten wird (was hier der Fall ist), der Wert für Monat 12 wird stets korrekt ermittelt.</p>
<p>&#160;</p>
<p>Einer der naheliegendsten Wege um diese Logik umzusetzen ist die Nutzung eines Cross Joins zwischen dem Jahreswert und 12 Monaten. Damit wird der Jahreswert von einer Zeile auf 12 Zeilen verteilt. Anschließend kann in einem &#8220;Abgeleitete Spalte&#8221;-Task der Wert mit Hilfe der oben beschriebenen Ausdrücke manipuliert werden.</p>
<p>&#160;</p>
<p>Folgender Screenshot zeigt den Datenfluss und zwei Data Viewer: einen nach dem Cross Join und einem nach dem Anwenden der Ausdrücke. Beachten Sie, dass sich der Wert für Monat 12 von allen anderen unterscheidet um einen korrekten Jahreswert zu gewährleisten.</p>
<p>&#160;</p>
<p><a href="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/cc00279c2c81_1174B/image.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/cc00279c2c81_1174B/image_thumb.png" width="572" height="291" /></a></p>
<p>&#160;</p>
<p>Im zweiten Teil zeige ich drei (!) weitere Vorgehensweisen, sowie die Ergebnisse eines Performancetests um zu ermitteln, wie sich die unterschiedlichen Wege im produktiven Einsatz bewähren könnten.</p>
<p></br></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/jahreswerte-auf-monate-verlustfrei-verteilen-teil-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sicheres Deployment einer BI-Lösung mit Bordmitteln und OpenSource-Tools</title>
		<link>http://www.ixto.de/blog/allgemein/sicheres-deployment-einer-bi-losung-mit-bordmitteln-und-opensource-tools/</link>
		<comments>http://www.ixto.de/blog/allgemein/sicheres-deployment-einer-bi-losung-mit-bordmitteln-und-opensource-tools/#comments</comments>
		<pubDate>Mon, 29 Nov 2010 13:34:18 +0000</pubDate>
		<dc:creator>Martin Ihrke</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=293</guid>
		<description><![CDATA[Die Bereitstellung einer Business Intelligence Lösung erscheint im ersten Moment als eine triviale Angelegenheit. Wer jedoch eine mühevoll und aufwendig entwickelte BI-Lösung nach erfolgreichem Test und Abnahme auf ein Produktivsystem übertragen musste, der weiss, wie mühevoll und aufwendig dieses Unterfangen trotz aller anfänglichen Vermutung sein kann.
Neben den technischen Herausforderungen, die eine für den rauen Betriebsalltag [...]]]></description>
			<content:encoded><![CDATA[<p>Die Bereitstellung einer Business Intelligence Lösung erscheint im ersten Moment als eine triviale Angelegenheit. Wer jedoch eine mühevoll und aufwendig entwickelte BI-Lösung nach erfolgreichem Test und Abnahme auf ein Produktivsystem übertragen musste, der weiss, wie mühevoll und aufwendig dieses Unterfangen trotz aller anfänglichen Vermutung sein kann.<br />
<span id="more-293"></span>Neben den technischen Herausforderungen, die eine für den rauen Betriebsalltag konfigurierte Umgebung mit sich bringt, sind auch fachliche Schwierigkeiten zu meistern, insbesondere dann, wenn eine bereits im laufenden Betrieb befindliche Lösung abgelöst werden soll. Einerseits sollen produktive Daten natürlich nicht verloren gehen, andererseits gilt es, Strukturänderungen und Steuerdaten vollständig und unbeschadet in die Produktivumgebung zu bringen. Es existieren zahlreiche Dritthersteller-Werkzeuge, die dies mehr oder weniger automatisch auf Knopfdruck realisieren können, diese kosten jedoch oft mehr als den sprichwörtlichen schmalen Taler und können damit das Projektbudget in die Höhe schnellen lassen. Aus diesem Grund möchte ich im folgenden Beitrag Lösungswege aufzeigen, die sich auf die Benutzung von SQL Server Bordmitteln und kostenlos erhältlichen OpenSource-Werkzeugen beschränken. Voraussetzung für das nachfolgend beschriebene Szenario ist, dass die produktive Umgebung nicht direkt aus der Entwicklungsumgebung erreichbar ist und somit nicht einfach ein direktes Deployment von dort aus geschehen kann. Ein Umstand, der aufgrund von strikten Sicherheitsbestimmungen sehr oft im realen Projektgeschäft angetroffen wird.</p>
<p><strong>Die Datenbank</strong></p>
<p>Zunächst sollte Klarheit darüber herrschen, welche Datenbankobjekte übertragen werden müssen. Vorbildliche Naturen können diese Frage mit einem Blick in die Historie ihrer professionellen Versionsverwaltung (natürlich inklusive Application LifeCycle Management) sogar des Nächtens im Halbschlaf beanworten (vielleicht haben sie auch mit Zettel und Stift mitgeschrieben), aber auch wenn diese Professionalität des Vorgehens nicht erreicht werden kann oder soll, gibt es es nützliche Hilfsmittel, die uns auf unter die Arme greifen helfen. Das OpenSource-Tool <em>OpenDBDiff</em> bietet die Möglichkeit, zwei Datenbank-Stände miteinander zu vergleichen. Es entsteht dabei ein SQL-Skript, dass ausgeführt auf der Zieldatenbank die ausgewählten Objekte synchronisiert. Dabei sei angemerkt, dass hierbei eigentlich nur Tabellenobjekte kritisch sind, da sich alle anderen, wie <em>Views</em>, <em>Stored Procedures</em> und <em>User-Defined Functions</em>, auch durch Löschen und Neu-Anlegen auf den gleichen Stand bringen lassen. Aber wenn wir OpenDBDiff ohnehin gestartet haben, sparen wir uns die Mühe.</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/mi_deployment/mi_01.png" alt="" /></p>
<p>Der zweite Schritt besteht im Abgleich von Steuerdaten, die zumeist in Konfigurationstabellen schlummern. Dazu kann uns das Tool TableDiff dienen, mit dessen Hilfe Unterschiede in Tabellendaten abgeglichen werden, indem auch hier SQL-Skripte generiert werden. Das Tool ist Bestandteil der SQL Server Installation und lässt sich zumeist unter <em>C:\Program Files\Microsoft SQL Server\100\COM</em> finden und aufrufen, wobei der Pfad je nach SQL Server Version und dessen Installationsverzeichnis varieren kann. TableDiff geht dabei tabellenweise vor, weshalb es sich anbietet, eine Batchdatei zu programmieren, die den Aufruf pro Tabelle automatisiert.</p>
<p>rem Server festlegen</p>
<p>set sserver=localhost</p>
<p>set dserver=localhost</p>
<p>rem Datenbanken festlegen</p>
<p>set sdb=AdventureWorksDW</p>
<p>set ddb=AdventureWorksDW2008</p>
<p>rem Pfade definieren</p>
<p>set exepath=&#8221;C:\Program Files\Microsoft SQL Server\100\COM\tablediff.exe&#8221;</p>
<p>set destfolder=D:\SQL</p>
<p>rem Schema festlegen</p>
<p>set schema=dbo</p>
<p>for %%t in (dimCurrency dimScenario) do (</p>
<p>%exepath% /sourceserver %sserver% /sourcedatabase %sdb% /sourceschema %schema%  /sourcetable %%t /destinationserver %dserver% /destinationdatabase %ddb% /destinationschema %schema% /destinationtable %%t -f &#8220;%destFolder%\changeScript(%schema%_%%t).sql&#8221;</p>
<p>)</p>
<p>Wir haben nun eine Reihe von SQL-Skripten, die nur noch auf der Zieldaten ausgeführt werden müssen, um die Datenbankstruktur in einen identischen Zustand zu bringen.</p>
<p><strong>SSIS-Pakete und Cube-Defintionen</strong></p>
<p>Es gilt nun, sowohl SSIS-Pakete und Cube-Definitionen zu übertragen. Dies ist etwas einfacher, da sowohl für SSIS- als für SSAS-Projekte einen Deployment-Wizard existiert, der uns das Bereitstellen auf dem Zielsystem (fast) vollständig abnimmt. Im Falle von SSIS-Paketen besteht weiterhin die Möglichkeit, auf das Kommandozeilenwerkzeug dtutil zurückzugreifen, das, eingebettet in eine Batch-Datei, das Bereitstellen der Pakete nach einem Doppelklick automatisch übernehmen kann. Da wir selbst in kleineren Projekten intensiven Gebrauch von der SSIS-Paketkonfiguration machen, haben wir auch wenig Mühe damit, Informationen wie Server- oder Datenbanknamen zu aktualisieren. SSAS-Cubes  müssen nur noch verarbeitet werden und sind damit direkt bereit zum Einsatz. Aber auch hier gilt es, eine gewisse Vorsicht an den Tag zu legen, da doch der ein oder andere Fallstrick lauert. Einer dieser Fallstricke sind Cube-Rollen, die ohne weitere Konfiguration auf dem Zielserver überschrieben werden. Doch auch wenn wir dies explizit verhindern wollen (die entsprechende Option im Deployment Wizard heißt <em>Retain Roles und Members</em>), ist leider nicht immer gewährleistet, dass die bestehende Konfiguration erhalten bleibt. Hier hat sich der Workaround etabliert, die Rollendefinition auf dem Produktivserver zu sichern (Zu finden im entsprechenden Bereich in der XMLA-Datei, also der Datenbankdefinition, auf der SSAS-Datenbank) und nach dem Deployment zurückzuspielen.</p>
<p><strong>Die Berichte</strong></p>
<p>Für SSRS-Berichte hat sich ein ein Werkzeug bewährt, dass es uns ermöglicht, Berichte direkt vom (Test)Berichtsserver herunterzuladen und auf den (Produktiv)Berichtsserver zu übertragen. Dazu wird neben den Berichtsdefinitionen in Form von .rdl-Dateien eine Batchdatei generiert, in der nur noch die URL des Zielsystems hinterlegt werden muss. Nach einem Doppelklick können wir und zurücklehnen und die Deployment-Show genießen.</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/mi_deployment/mi_02.png" alt="" /></p>
<p><strong>Fazit</strong></p>
<p>Mit dem vorgestellen Vorgehen und Werkzeugen ist es uns, ein recht elegantes Deployment unserer BI-Solution auf entfernte Umgebungen vorzunehmen. Großer Vorteil dabei ist die Möglichkeit, weite Teile durch Batch-Dateien und Konfigurationen zu automatisieren und damit den Aufwand mehrmaliger Deployments zu merklich reduzieren.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/allgemein/sicheres-deployment-einer-bi-losung-mit-bordmitteln-und-opensource-tools/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SSAS 2005 MDX Simple CASE WHEN &#8211; Probleme im ELSE Zweig</title>
		<link>http://www.ixto.de/blog/sql-server-2005/analysis-services-2005/ssas-2005-mdx-simple-case-when-probleme-im-else-zweig/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/analysis-services-2005/ssas-2005-mdx-simple-case-when-probleme-im-else-zweig/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 16:06:26 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Analysis Services 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=275</guid>
		<description><![CDATA[Manchmal, aus welch guten oder schlechten Gründen auch immer, muss man in berechneten Measures eines SSAS 2005 Cubes mehrere Zustände eines Members unterschiedlich behandeln. Dies erreicht man durch die Verwendung von IIF Statements, oder, ein wenig bequemer, durch die Verwendung von CASE WHEN Statements.

Das CASE WHEN Statement  wird in zwei Typen unterteilt:
A) “Simple” CASE:
CASE [MyValue]
  [...]]]></description>
			<content:encoded><![CDATA[<p>Manchmal, aus welch guten oder schlechten Gründen auch immer, muss man in berechneten Measures eines SSAS 2005 Cubes mehrere Zustände eines Members unterschiedlich behandeln. Dies erreicht man durch die Verwendung von IIF Statements, oder, ein wenig bequemer, durch die Verwendung von CASE WHEN Statements.<br />
<span id="more-275"></span></p>
<p>Das CASE WHEN Statement  wird in zwei Typen unterteilt:</p>
<p>A) “Simple” CASE:</p>
<p>CASE [MyValue]<br />
  WHEN 100 THEN „Small“<br />
  WHEN 1000 THEN “Middle”<br />
  WHEN 10000 THEN “Large”<br />
ELSE “Micro” END</p>
<p>B) “Searched” CASE:</p>
<p>CASE<br />
  WHEN [MyValue] = 100 THEN „Small“<br />
  WHEN [MyValue] = 1000 THEN “Middle”<br />
  WHEN [MyValue] = 10000 THEN “Large”<br />
ELSE “Micro”<br />
END</p>
<p>Wie Chris Webb in seinem <a href="http://cwebbbi.wordpress.com/2009/12/09/simple-vs-searched-case-statements/">BI-Blog</a> mitteilt, ist die Verwendung von Simple CASE performanter als Searched CASE, allerdings kann in der SQL Server Version 2005 die Verwendung von Simple CASE unter gewissen Umständen fehlerhafte Ergebnisse im ELSE Zweig erzeugen.</p>
<p>Voraussetzung dafür ist, dass in irgendeinem der Zweige ein anderes, berechnetes Measure benutzt wird, welches wiederum aus einem Tupel mit mindestens einer Dimensionsreferenz bestehen muss. Bsp:</p>
<p><span style="color: #0000ff;">CREATE MEMBER CURRENTCUBE</span>.[Measures].TestCalc <span style="color: #0000ff;">AS</span></p>
<p>([Date].[Calendar Year].&amp;[2003],[Measures].[Sales Amount]),</p>
<p><span style="color: #0000ff;">Visible</span>=1,<span style="color: #0000ff;">FORMAT_STRING</span>=<span style="color: #a30000;">&#8220;#,###0.00&#8243;</span>;</p>
<p>Folgend die Definition eines berechneten Elements mit einer SIMPLE CASE Entscheidung auf Basis der AdventureWorks DW 2005 OLAP Datenbank:<br />
<em>(Ich bitte den Sinn der angeführten Berechnungen in den Hintergrund zu stellen … <img src='http://www.ixto.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </em></p>
<p><span style="color: #0000ff;">CREATE MEMBER CURRENTCUBE</span>.[Measures].SimpleCase <span style="color: #0000ff;">AS</span></p>
<p><span style="color: #0000ff;">CASE</span> [Date].[Calendar Year].<span style="color: #a30000;">CURRENTMEMBER</span></p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].&amp;[2002] <span style="color: #0000ff;">THEN</span></p>
<p>      ([Product].[Product Line].&amp;[S],[Measures].TestCalc)</p>
<p>    + ([Product].[Product Line].&amp;[],[Measures].TestCalc)</p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].&amp;[2003] <span style="color: #0000ff;">THEN</span></p>
<p>      ([Product].[Product Line].&amp;[],[Measures].[Sales Amount])</p>
<p>    + ([Product].[Product Line].&amp;[S],[Measures].[Sales Amount])</p>
<p>    <span style="color: #0000ff;">ELSE</span>   <span style="color: #008000;">&#8211; &#8220;Any other year – Product line MOUNTAIN</span></p>
<p>      ([Product].[Product Line].&amp;[M],[Measures].[Sales Amount])</p>
<p><span style="color: #0000ff;">END</span>,</p>
<p><span style="color: #0000ff;">Visible</span>=1,<span style="color: #0000ff;">FORMAT_STRING</span>=<span style="color: #a30000;">&#8220;#,###0.00&#8243;</span>;</p>
<p>Das Measure summiert die Produktlinien „Accessorys“ und „Components“ in den Pfaden 2002 und 2003, benutzt im Pfad für das Jahr 2002 das Measure „TestCalc“ und zeigt im ELSE Zweig den Sales Amount der Produktinie „Mountain“ an.<em> </em></p>
<p>Ein berechnetes Element mit Verwendung der Searched CASE Variante würde dann wie folgt definiert werden müssen:</p>
<p><span style="color: #0000ff;">CREATE MEMBER CURRENTCUBE</span>.[Measures].SearchedCase <span style="color: #0000ff;">AS</span></p>
<p><span style="color: #0000ff;">CASE</span></p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].<span style="color: #a30000;">CURRENTMEMBER</span></p>
<p>     <span style="color: #0000ff;">IS</span> [Date].[Calendar Year].&amp;[2002] <span style="color: #0000ff;">THEN</span></p>
<p>     ([Product].[Product Line].&amp;[S],[Measures].TestCalc)</p>
<p>   + ([Product].[Product Line].&amp;[],[Measures].TestCalc)</p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].<span style="color: #a30000;">CURRENTMEMBER</span></p>
<p>      <span style="color: #0000ff;">IS</span> [Date].[Calendar Year].&amp;[2003] <span style="color: #0000ff;">THEN</span></p>
<p>      ([Product].[Product Line].&amp;[S],[Measures].[Sales Amount])</p>
<p>    + ([Product].[Product Line].&amp;[],[Measures].[Sales Amount])</p>
<p>    <span style="color: #0000ff;">ELSE</span>   <span style="color: #008000;">&#8211; &#8220;Any other year – Product line MOUNTAIN</span></p>
<p>     ([Product].[Product Line].&amp;[M],[Measures].[Sales Amount])</p>
<p>    <span style="color: #0000ff;">END</span>,</p>
<p><span style="color: #0000ff;">Visible</span>=1,<span style="color: #0000ff;">FORMAT_STRING</span>=<span style="color: #a30000;">&#8220;#,###0.00&#8243;</span>;</p>
<p>Das Ergebnis ist verblüffend, zieht man beide berechneten Member in die Abfrage eines Cubebrowsers:</p>
<p>Zeilen   : Dimension Promotion, Attribut Promotion<br />
Filter    : Date.Calendar Year = 2004; Product.Product Line = Mountain</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/me_ssas_05.jpg" alt="" /></p>
<p>Wie man sieht, wird die Gesamtsumme in beiden Membern korrekt angezeigt, im Simple CASE Measure werden jedoch die Ergebnisse für die unteren beiden Zeilen NICHT angezeigt. Das Phänomen / Bug tritt NUR im SQL Server 2005 auf und NUR bei Verwendung eines berechneten Measures mit o.g. Bedingungen in irgendeinem der CASE Zweige.</p>
<p>Gefährlich bleibt es trotzdem, kontrolliert man nämlich nur die Gesamtsummen (was der eine oder andere Developer aus Zeitgründen sicher schon mal getan hat), fällt der Fehler eben NICHT auf.</p>
<p>Deswegen:</p>
<p>Checkt Eure CASE WHEN Member! Vor allem darauf ob Ihr Euch die Verwendung nicht ganz sparen wollt/könnt <img src='http://www.ixto.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/analysis-services-2005/ssas-2005-mdx-simple-case-when-probleme-im-else-zweig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deaktivieren von Reporting Services Abonnements</title>
		<link>http://www.ixto.de/blog/sql-server-2005/reportingservices/deaktivieren-von-reporting-services-abonnements/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/reportingservices/deaktivieren-von-reporting-services-abonnements/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 14:50:16 +0000</pubDate>
		<dc:creator>Sven Bayer</dc:creator>
				<category><![CDATA[Reporting Services 2005]]></category>
		<category><![CDATA[Reporting Services 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=145</guid>
		<description><![CDATA[Wenn man häufiger mit den Abonnements der Reporting Services zu tun hat, musste der ein oder andere, ich leider auch, mit bedauern feststellen, dass es keine Möglichkeit gibt die angelegten Abonnements zu deaktivieren. Um das Verenden eines Berichts zu verhindern, konnte man dessen Abonnement entweder löschen oder den Zeitpunkt für die Ausführung weit in die [...]]]></description>
			<content:encoded><![CDATA[<p>Wenn man häufiger mit den Abonnements der Reporting Services zu tun hat, musste der ein oder andere, ich leider auch, mit bedauern feststellen, dass es keine Möglichkeit gibt die angelegten Abonnements zu deaktivieren. Um das Verenden eines Berichts zu verhindern, konnte man dessen Abonnement entweder löschen oder den Zeitpunkt für die Ausführung weit in die Zukunft verlegen. Für mich zwei Methoden, die nicht wirklich benutzerfreundlich sind, entweder muss ich das Abonnement neu anlegen oder ich muss darauf achten meine Zeitänderungen wieder rückgängig zu machen und hab keine richtige Kontrolle über aktivierte oder deaktivierte Abonnements.</p>
<p> Ich möchte hier kurz beschreiben, wie es möglich ist, unter Verwendung der <em>ReportServer</em> Datenbank, die Ausführung der Abonnements einfach zu verwalten.</p>
<p><span id="more-145"></span><br />
<br\></p>
<h2>Die Grundidee</h2>
<p><br\><br />
Die Reporting Services speichern ihre Abonnements in der zugehörigen DB(Standardname: <em>ReportServer</em>). Die Tabelle in der alle Abonnements aufgeführt sind nennt sich <em>dbo.Subscriptions</em>:</p>
<p><img class="alignnone" title="Tabelle" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/SB/blog1.png" alt="" width="1059" height="648" /><br />
<br\><br />
In dieser Tabelle gibt es eine Spalte mit dem Namen <em>InactiveFlags</em>. Bei einem aktiven Abo ist dieser Wert auf 0 gesetzt. Um das Abo zu deaktivieren muss dieser Wert auf 1 geändert werden.<br />
<br\><br />
<br\></p>
<h2>Die Umsetzung</h2>
<p><br\><br />
Zunächst benötigen wir noch einige Tabellen, um die Lesbarkeit zu erhöhen, indem wir die IDs durch die zugehörigen Namen für Bericht, Abonnement und Benutzer ersetzen:</p>
<div>
<table style="border-collapse: collapse;" border="0">
<colgroup span="1">
<col style="width: 191px;" span="1"></col>
<col style="width: 181px;" span="1"></col>
<col style="width: 18px;" span="1"></col>
<col style="width: 251px;" span="1"></col>
</colgroup>
<tbody>
<tr style="background: black;">
<td style="padding-left: 7px; padding-right: 7px; border-top: solid black 1.5pt; border-left: solid black 1.5pt;"><span style="color: white; font-family: Times New Roman; font-size: 10pt;"><strong>Tabelle</strong></span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid black 1.5pt;" colspan="2"><span style="color: white; font-family: Times New Roman; font-size: 10pt;"><strong>Information</strong></span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid black 1.5pt; border-right: solid black 1.5pt;"> </td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-left: solid black 1.5pt;">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">Dbo.Users u</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px;">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">Benutzername</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px; border-right: solid black 1.5pt;" colspan="2">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">u.UserID = OwnerID</span></p>
</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-left: solid black 1.5pt;">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">Dbo.Catalog c</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px;">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">Berichtsname</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px; border-right: solid black 1.5pt;" colspan="2">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">c.ItemID = Report_OID</span></p>
</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-left: solid black 1.5pt; border-bottom: solid black 1.5pt;">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">[dbo].[ReportSchedule] rs</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px; border-bottom: solid black 1.5pt;">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">SQL Server Agent Job Name</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px; border-bottom: solid black 1.5pt; border-right: solid black 1.5pt;" colspan="2">
<p style="text-align: justify;"><span style="font-family: Times New Roman; font-size: 10pt;">SubscriptionID = rs.SubscriptionID</span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p> <br />
<br\><br />
Mit dem nachfolgendem SQL-Statement können wir die passenden Informationen auslesen:<br />
<br\><br />
<span style="font-family: Courier New;"><span style="color: blue;">SELECT<br />
</span>     s<span style="color: gray;">.</span>[SubscriptionID]<br />
     </span><span style="color: gray;">,</span>s<span style="color: gray;">.</span>[Description]<br />
             <span style="color: gray;">,</span>u<span style="color: gray;">.</span>UserName<br />
<span style="color: gray;">             ,</span>c<span style="color: gray;">.</span>Name as ReportName<br />
             <span style="color: gray;">,</span>[InactiveFlags]<br />
             <span style="color: gray;">,</span>rs<span style="color: gray;">.</span>ScheduleID <span style="color: blue;">AS</span> JobName<br />
             <span style="color: gray;">,</span>rs<span style="color: gray;">.</span>ReportAction<br />
             <span style="color: gray;">,</span>[ExtensionSettings]<br />
             <span style="color: gray;">,</span>[Locale]<br />
             <span style="color: gray;">,</span>s<span style="color: gray;">.</span>[ModifiedByID]<br />
             <span style="color: gray;">,</span>s<span style="color: gray;">.</span>[ModifiedDate]<br />
             <span style="color: gray;">,</span>[LastStatus]<br />
             <span style="color: gray;">,</span>[EventType]<br />
             <span style="color: gray;">,</span>[MatchData]<br />
             <span style="color: gray;">,</span>[LastRunTime]<br />
             <span style="color: gray;">,</span>[Parameters]<br />
             <span style="color: gray;">,</span>[DataSettings]<br />
             <span style="color: gray;">,</span>[DeliveryExtension]<br />
             <span style="color: gray;">,</span>[Version]<br />
             <span style="color: gray;">,</span>[ReportZone]<br />
             <span style="color: gray;">,</span>[OwnerID]<br />
             <span style="color: gray;">,</span>[Report_OID]<br />
<span style="color: blue;">FROM</span> [ReportServer]<span style="color: gray;">.</span>[dbo]<span style="color: gray;">.</span>[Subscriptions] s<br />
<span style="color: gray;">             inner </span><span style="color: gray;">join</span> dbo<span style="color: gray;">.</span>Users u <span style="color: blue;">on</span> u<span style="color: gray;">.</span>UserID <span style="color: gray;">=</span> OwnerID<br />
             <span style="color: gray;">inner </span><span style="color: gray;">join</span> [dbo]<span style="color: gray;">.</span>[Catalog] c <span style="color: blue;">on</span> s<span style="color: gray;">.</span>Report_OID <span style="color: gray;">=</span> c<span style="color: gray;">.</span>ItemID<br />
             <span style="color: gray;">inner </span><span style="color: gray;">join</span> [dbo]<span style="color: gray;">.</span>[ReportSchedule] rs <span style="color: blue;">on</span> s<span style="color: gray;">.</span>SubscriptionID <span style="color: gray;">=</span> rs<span style="color: gray;">.</span>SubscriptionID<br />
<br\><br />
Abhängig von den Abonnements sollte die Abfrage in etwa das folgende Ergebnis liefern:</p>
<div>
<table style="border-collapse: collapse;" border="0">
<colgroup span="1">
<col style="width: 126px;" span="1"></col>
<col style="width: 169px;" span="1"></col>
<col style="width: 115px;" span="1"></col>
<col style="width: 109px;" span="1"></col>
<col style="width: 122px;" span="1"></col>
</colgroup>
<tbody>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border: solid 0.5pt;"><span style="font-family: Times New Roman;">SubscriptionID</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid 0.5pt; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">Description</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid 0.5pt; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">UserName</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid 0.5pt; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">
<p style="text-align: center;"><span style="font-family: Times New Roman;">ReportName</span></p>
</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid 0.5pt; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">InactiveFlags</span></td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">929CDEE8-…</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">In &#8216;…&#8217; unter &#8216;Arbeitszeit Übersicht&#8217; speichern</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Domäne\Bayer</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">Arbeitszeit Übersicht</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">0</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">7A4B049E-…</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">In &#8216;…&#8217; unter &#8216;</span><br />
<span style="font-family: Times New Roman;">Fluktuation &#8216; speichern</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Domäne\Bayer</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Fluktuation</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">0</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">23E7F4EF-…</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;"><span style="font-family: Times New Roman;">In &#8216;…&#8217; unter Haushalt&#8217; speichern</span></td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Domäne\Bayer</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Haushalt</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">0</td>
</tr>
</tbody>
</table>
</div>
<p> <br />
<br\><br />
Mit den oben stehenden Informationen können wir jetzt einzelne Abonnements aktivieren bzw. deaktivieren.<br />
<br\><br />
Für die Deaktivierung kann folgende Query verwendet werden:</p>
<p><span style="font-family: Courier New;">UPDATE Subscriptions set<br />
[InactiveFlags] = 1<br />
where<br />
[SubscriptionID] = &#8216;929CDEE8-…&#8217;<br />
END<br />
</span></p>
<p>Für die Aktivierung kann das gleiche Update-Statement verwendet werden, der Wert <em>InactiveFlags</em> muss jetzt nur auf 0 gesetzt werden.<br />
<br\><br />
<br\></p>
<h2>Ausführung von Abonnements</h2>
<p><br\><br />
Gelegentlich kommt es vor, dass ein Abonnement außerhalb der geplanten Zeiten durchgeführt werden soll.<br />
<br\><br />
Da die Ausführung der Abonnements über den SQL Server Agent gesteuert wird, haben wir die Möglichkeit die passenden Jobs von Hand zu starten. Dies kann im SQL Server Management Studio erfolgen.</p>
<p><img title="Tabelle" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/SB/blog2.png" alt="" /><br />
<br\><br />
Oder es können vordefinierte gespeicherte Prozeduren aus der msdb Datenbank verwendet werden.<br />
<br\><br />
<em>EXEC msdb.dbo.sp_start_job ‚251601B4…&#8217;<br />
</em><br />
<br\><br />
Die IDs der für die angelegten Jobs und die IDs für die zugehörigen Abos sind in der <em>[dbo].[ReportSchedule] </em>Tabelle der <em>ReportServer</em> DB hinterlegt. Wenn man diese Tabelle noch mit der <em>dbo.Subscriptions</em> verbindet:</p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SELECT</span><br />
<span style="color: #0000ff;">   </span>[ScheduleID]<br />
  </span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: gray;">,</span>[ReportID]<br />
</span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: gray;">  ,</span>rs<span style="color: gray;">.</span>[SubscriptionID]<br />
</span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: gray;">  ,</span>s<span style="color: gray;">.<span style="color: blue;">Description<br />
</span></span></span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: gray;">  ,</span>[ReportAction]<br />
</span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">FROM</span> [dbo]<span style="color: gray;">.</span>[ReportSchedule] rs<br />
</span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: gray;">INNER </span><span style="color: gray;">JOIN</span> dbo<span style="color: gray;">.</span>Subscriptions s <span style="color: blue;">ON</span> rs<span style="color: gray;">.</span>SubscriptionID <span style="color: gray;">=</span> s<span style="color: gray;">.</span>SubscriptionID<br />
</span><br />
können die JobIDs den zugehörigen Abos zugeordnet werden.<br />
<br\><br />
<br\></p>
<h2>Der passende Bericht</h2>
<p><br\><br />
Nachdem die Grundlagen für die Deaktivierung bzw. Aktivierung der Abonnements geklärt sind, kann ein einfacher Bericht erstellt werden, mit dem die Ausführung und der Status des Abos gesteuert werden kann.</p>
<p><img title="Tabelle" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/SB/blog3.png" alt="" /><br />
<br\><br />
Für den Bericht muss eine Datenquelle für die <em>ReportServer</em> Datenbank erstellt werden und die folgenden Parameter werden benötigt, um die zugehörigen Funktionalitäten zu gewährleisten:</p>
<div>
<table style="border-collapse: collapse;" border="0">
<colgroup span="1">
<col style="width: 187px;" span="1"></col>
<col style="width: 83px;" span="1"></col>
<col style="width: 372px;" span="1"></col>
</colgroup>
<tbody>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border: solid 0.5pt;">Parameter</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid 0.5pt; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Typ</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: solid 0.5pt; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Beschreibung</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">SetActiv</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Text (0,1) Default: 0</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">0 – Keine Aktion wird ausgeführt1 – Der Status des ausgewählten Abos wird geändert</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">SubscriptionID</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Text</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">ID des Abos.Blank und null Value aktiviert</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">JobName</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Text</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">ID des JobsBlank und null Value aktiviert</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">InactiveFlags</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Text</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Neue Status für das zugehörige Abo0 – aktiviert1 – deaktiviert</p>
<p>Blank und null Value aktiviert</td>
</tr>
<tr>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: solid 0.5pt; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Execute</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Text (0,1)</td>
<td style="padding-left: 7px; padding-right: 7px; border-top: none; border-left: none; border-bottom: solid 0.5pt; border-right: solid 0.5pt;">Job0 – nicht ausführen1 &#8211; ausführen</td>
</tr>
</tbody>
</table>
</div>
<p><br\><br />
Des Weiteren brauchen wir ein Dataset, das zum einen die Informationen, wie vorhandene Abos, Berichtsnamen, etc. ermittelt, um sie im Bericht anzuzeigen, zum anderen aber auch Abos aktiviert und deaktiviert, sowie einzelne Jobs ausführt. Die Steuerung der Ausführung wird durch die einzelnen Parameter vollzogen und einzelne Teile der Abfrage übergangen oder ausgeführt:</p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">if</span> @SetActiv <span style="color: gray;">=</span> 1<br />
</span><span style="color: blue; font-family: Courier New; font-size: 10pt;">BEGIN<br />
</span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">UPDATE</span> Subscriptions <span style="color: blue;">set </span></span><span style="font-family: Courier New; font-size: 10pt;">[InactiveFlags] <span style="color: gray;">=</span> @InactiveFlags<br />
</span><span style="color: blue; font-family: Courier New; font-size: 10pt;">where<br />
    </span><span style="font-family: Courier New; font-size: 10pt;">[SubscriptionID] <span style="color: gray;">=</span> @id<br />
</span><span style="color: blue; font-family: Courier New; font-size: 10pt;">END<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">if</span> @Execute <span style="color: gray;">=</span> 1<br />
</span><span style="color: blue; font-family: Courier New; font-size: 10pt;">BEGIN<br />
</span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">EXEC</span> msdb<span style="color: gray;">.</span>dbo<span style="color: gray;">.<span style="color: maroon;">sp_start_job @JobName<br />
</span></span></span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">WAITFOR</span><br />
<span style="color: blue;">delay </span><span style="color: red;">&#8216;00:00:05&#8242;<br />
</span></span><span style="color: blue; font-family: Courier New; font-size: 10pt;">END<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SELECT</span> s<span style="color: gray;">.</span>SubscriptionID<span style="color: gray;">,</span> rs<span style="color: gray;">.</span>ScheduleID <span style="color: blue;">AS</span> JobName<span style="color: gray;">,</span> s<span style="color: gray;">.</span>OwnerID<span style="color: gray;">,</span> u<span style="color: gray;">.</span>UserName<span style="color: gray;">,</span> s<span style="color: gray;">.</span>Report_OID<span style="color: gray;">,</span> c<span style="color: gray;">.</span>Name <span style="color: blue;">AS</span> Reportname<span style="color: gray;">,</span> s<span style="color: gray;">.<span style="color: blue;">Description </span><span style="color: blue;">AS</span> SubDesc,</span> s<span style="color: gray;">.</span>InactiveFlags <span style="color: blue;">AS</span> Active<span style="color: gray;">, </span></span><span style="font-family: Courier New; font-size: 10pt;">s<span style="color: gray;">.</span>ExtensionSettings<span style="color: gray;">,</span> s<span style="color: gray;">.</span>Locale<span style="color: gray;">,</span> s<span style="color: gray;">.</span>ModifiedByID<span style="color: gray;">,</span> s<span style="color: gray;">.</span>ModifiedDate<span style="color: gray;">,</span> s<span style="color: gray;">.</span>LastStatus<span style="color: gray;">,</span> s<span style="color: gray;">.</span>EventType<span style="color: gray;">,</span> s<span style="color: gray;">.</span>MatchData<span style="color: gray;">,</span> s<span style="color: gray;">.</span>LastRunTime<span style="color: gray;">,</span> s<span style="color: gray;">.<span style="color: green;">Parameters<span style="color: gray;">,</span> s<span style="color: gray;">.</span>DataSettings<span style="color: gray;">, </span></span></span></span><span style="font-family: Courier New; font-size: 10pt;">s<span style="color: gray;">.</span>DeliveryExtension<span style="color: gray;">,</span> s<span style="color: gray;">.<span style="color: blue;">Version<span style="color: gray;">,</span> s<span style="color: gray;">.</span>ReportZone<br />
</span></span></span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">FROM</span> Subscriptions <span style="color: blue;">AS</span> s<br />
   </span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: gray;">INNER </span><span style="color: gray;">JOIN </span></span><span style="font-family: Courier New; font-size: 10pt;">Users <span style="color: blue;">AS</span> u <span style="color: blue;">ON</span> u<span style="color: gray;">.</span>UserID <span style="color: gray;">=</span> s<span style="color: gray;">.</span>OwnerID<br />
   <span style="color: gray;">INNER </span><span style="color: gray;">JOIN </span></span><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">Catalog </span><span style="color: blue;">AS</span> c <span style="color: blue;">ON</span> s<span style="color: gray;">.</span>Report_OID <span style="color: gray;">=</span> c<span style="color: gray;">.</span>ItemID<br />
   <span style="color: gray;">INNER </span><span style="color: gray;">JOIN </span></span><span style="font-family: Courier New; font-size: 10pt;">ReportSchedule <span style="color: blue;">AS</span> rs <span style="color: blue;">ON</span> s<span style="color: gray;">.</span>SubscriptionID <span style="color: gray;">=</span> rs<span style="color: gray;">.</span>SubscriptionID<br />
</span><br />
<br\><br />
Im unteren Teil der Abfrage werden die Informationen ermittelt, im oberen Teil wird zunächst der Status des Abos aktualisiert oder der ausgewählte Job gestartet. Dadurch, dass das Statusänderungen und Jobausführungen über die Links in der Tabelle gesteuert werden, ist immer nur einer der beiden Parameter @SetActiv und @Execute eins und es wird immer nur eine der beiden Aktionen ausgeführt.<br />
<br\><br />
Um die Daten anzuzeigen erstellen wir eine einfache Tabelle:<br />
<img title="Tabelle" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/SB/blog3a.png" alt="" /><br />
<br\><br />
Für das Feld Aktiv wird die folgende Expression: <span style="font-family: Courier New; font-size: 10pt;">=iif(Fields!Active.Value = 0,<span style="color: #a31515;">&#8220;Aktiv&#8221;</span>,<span style="color: #a31515;">&#8220;Deaktiviert&#8221;</span>) </span>verwendet und die folgende Aktion, für die Änderung des Status, definiert:<br />
<img title="Tabelle" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/SB/blog4.png" alt="" /><br />
<br\><br />
Zum Schluss muss noch das Ausführen des Jobs ermöglicht werden. Hierfür definieren wir eine Aktion für das Textfeld Execute:<br />
<img title="Tabelle" src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/SB/blog5.png" alt="" /><br />
Jetzt ist der Bericht soweit fertig, dass der Status und das Ausführen der Abos verwaltet werden kann, birgt aber noch die ein oder andere Gefahr in sich. So wird z.B. ein Abo erneut ausgeführt, wenn man den Bericht nach einem <em>Execute </em>aktualisiert. Für eine erste Demonstration sollte er aber reichen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/reportingservices/deaktivieren-von-reporting-services-abonnements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MS-DOS lebt – im ForEachLoop-SSIS Container!</title>
		<link>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/ms-dos-lebt-%e2%80%93-im-foreachloop-ssis-container-2/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/ms-dos-lebt-%e2%80%93-im-foreachloop-ssis-container-2/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 21:32:12 +0000</pubDate>
		<dc:creator>Chris Jacob</dc:creator>
				<category><![CDATA[Integration Services 2005]]></category>
		<category><![CDATA[Integration Services 2008]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=91</guid>
		<description><![CDATA[Wer hätte gedacht dass man heutzutage noch über die Vermächtnisse einer 20 Jahre alten Software stolpern kann – und das in den Integration Services!
Aber beginnen wir von vorne: immer wenn die Bearbeitung mehrere gleichartiger Dateien mittels SSIS gefragt ist, kommt früher oder später der ForEach-Loop-Container zum Einsatz. Damit lässt sich z.B. recht komfortabel über Dateien [...]]]></description>
			<content:encoded><![CDATA[<p>Wer hätte gedacht dass man heutzutage noch über die Vermächtnisse einer 20 Jahre alten Software stolpern kann – und das in den Integration Services!</p>
<p>Aber beginnen wir von vorne: immer wenn die Bearbeitung mehrere gleichartiger Dateien mittels SSIS gefragt ist, kommt früher oder später der ForEach-Loop-Container zum Einsatz. Damit lässt sich z.B. recht komfortabel über Dateien mit einer bestimmten Namensstruktur innerhalb eines Ordners iterieren. So könnte ein mögliches Importszenario vorsehen, dass mehrere Exceldateien in einem Ordner ausgelesen werden sollen – den ForEach-Loop-Container könnte man dann wie folgt konfigurieren:</p>
<p><span id="more-91"></span><br />
<br\><br />
Soweit so gut, der Rest des Paketes könnte dann wie folgt aussehen. Innerhalb des Loops wird eine Variable mit dem aktuellen Dateipfad ausgelesen um alle gefundenen Dateien nach Beendigung des Containers in einer MessageBox anzuzeigen:<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/042910_2132_MSDOSlebti2.png" alt="" /><br />
<br\><br />
Ich habe bisher den Inhalt des betroffenen Ordners unterschlagen, hier ist er:<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/042910_2132_MSDOSlebti3.png" alt="" /><br />
<br\><br />
Und siehe da: unser Paket findet zwei Exceldateien – wunderbar! Oder doch nicht? Störend an dieser Stelle könnte die Excel-Datei sein, die im neuen 2007er Format gespeichert wurde. Diese hat die Endung .xlsx! Eigentlich ganz praktisch, denn die beiden Exceltypen unterscheiden sich grundlegend und erfordern ggf. eine differenzierte Behandlung innerhalb der SSIS. Weitere prüfende Blicke in die Konfiguration des ForEach-Loops lassen letztlich nur einen Schluss zu: egal wie man es dreht und wendet, der Ausdruck im &#8220;Files&#8221;-Feld des Editors lässt sich nicht dahingehend ändern dass er nur .xls Dateien erwischt (was man eigentlich erwarten würde) – der Ausdruck verhält sich also wie *.xls*!<br />
<br\><br />
An dieser Stelle wirken die Books Online einmal mehr erhellend und decken auf, dass es sich quasi um erwünschtes Verhalten handelt – der Ausdruck verhält sich nämlich wie beim dir-Befehl in Windows (siehe: <a href="http://msdn.microsoft.com/en-us/library/ms187670.aspx">http://msdn.microsoft.com/en-us/library/ms187670.aspx</a>). Dieser wiederum ist aus Kompatibilitätsgründen so gestrickt, dass er nur drei Zeichen der Dateinamenerweiterung betrachtet – die gute alte 8.3-Dateinamenbeschränkung aus MS-DOS Zeiten schlägt hier also wieder einmal zu!<br />
<br\><br />
Eine Differenzierung nach Dateierweiterung muss also später geschehen, die könnte dann z.B. so aussehen: innerhalb des ForEach-Loop-Containers fügen wir eine Rangfolgeeinschränkung (zu deutsch: einen Pfeil) ein und binden daran eine SSIS-Expression. Diese prüft, ob die letzten drei Buchstaben des ausgelesenen Dateinamens auch tatsächlich x, l und s sind:<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/042910_2132_MSDOSlebti4.png" alt="" /><br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/042910_2132_MSDOSlebti5.png" alt="" /><br />
<br\><br />
So modifiziert, verrichtet das Paket ordnungsgemäß seinen Dienst und findet tatsächlich nur eine Excel-Datei:<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/042910_2132_MSDOSlebti6.png" alt="" /><br />
<br\><br />
Da kann man sich natürlich schon fragen ob es sich um ein Bug oder ein Feature handelt, aber genau wegen diesen Ecken und Kanten lieben wir die Integration Services so sehr – man entdeckt eben immer wieder etwas Neues!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/ms-dos-lebt-%e2%80%93-im-foreachloop-ssis-container-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Codeplex Perlen &#8211; heute: Enhanced SSIS Execute Package Task</title>
		<link>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/codeplex-perlen-heute-enhanced-ssis-execute-package-task/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/codeplex-perlen-heute-enhanced-ssis-execute-package-task/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 13:33:26 +0000</pubDate>
		<dc:creator>Chris Jacob</dc:creator>
				<category><![CDATA[Integration Services 2005]]></category>
		<category><![CDATA[Integration Services 2008]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=81</guid>
		<description><![CDATA[Divide et impera – das von Machiavelli vor gut 500 Jahren geprägte Prinzip des Teilen und Herrschens ist heutzutage eine allseits beliebte Technik zur Problemlösung. Auch in den Integration Services finden sich eine Menge Möglichkeiten, um große Aufgaben in kleinere, übersichtliche Schritte zu unterteilen. Beispiele sind unterschiedliche Datenflüsse für unterschiedliche Aufgaben, die Strukturierung mittels Sequenzcontainern [...]]]></description>
			<content:encoded><![CDATA[<p>Divide et impera – das von Machiavelli vor gut 500 Jahren geprägte Prinzip des Teilen und Herrschens ist heutzutage eine allseits beliebte Technik zur Problemlösung. Auch in den Integration Services finden sich eine Menge Möglichkeiten, um große Aufgaben in kleinere, übersichtliche Schritte zu unterteilen. Beispiele sind unterschiedliche Datenflüsse für unterschiedliche Aufgaben, die Strukturierung mittels Sequenzcontainern und nicht zuletzt die Möglichkeit, aus einem SSIS Paket andere SSIS Pakete aufzurufen.</p>
<p><span id="more-81"></span><br />
<br\><br />
Doch mit steigender Komplexität der Pakete (Verbindungsmanager, Paketvariablen) und ausgiebiger Nutzung der Paketkonfiguration gelangt man mit den SSIS-Bordmitteln einmal mehr an die Grenzen des Wartbaren. Die Integration Services bieten von Haus aus die Möglichkeit, andere SSIS Pakete aufzurufen, doch die Übergabe von Variablen und Verbindungsmanagern an das &#8220;Kindpaket&#8221; gestaltet sich sehr aufwändig (viel Expression-Hacking). Die Möglichkeit, Rückgabewerte vom Kindpaket zu empfangen fehlt gar gänzlich.<br />
<br\><br />
In diese Nische stürzt sich ein Codeplex-Projekt, welches ich im Folgenden kurz vorstellen möchte: der &#8220;Enhanced SSIS Execute Package Task&#8221;. Unter <a href="http://ssisexec.codeplex.com/">http://ssisexec.codeplex.com/</a> ist das noch recht unbekannte Projekt zu finden (derzeit für SSIS 2005 und SSIS 2008 R2 – siehe &#8220;Downloads&#8221;). Hilfreich bei der Installation (es wird eine dll und ein schmales readme geliefert) ist folgender Eintrag in den Books Online: <a href="http://msdn.microsoft.com/en-us/library/ms403356.aspx">http://msdn.microsoft.com/en-us/library/ms403356.aspx</a> Hat man die Komponente erfolgreich installiert lässt sie sich über einen Rechtsklick in die Toolbox -&gt; Choose Items in die Liste der Kontrollfluss Tasks aufnehmen.<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/enhanced_1.png" alt="" /><br />
<br\><br />
Die Komponente bietet eine grafische Oberfläche zum Mappen der Variablen bzw. Verbindungsmanagern zwischen den Paketen. Diese können entweder im Dateisystem oder in der MSDB serverseitig gespeichert sein. Somit lassen sich recht schnell und komfortabel Konfigurationen zwischen Paketen übergeben. Wie das aussehen könnte sieht man in folgendem screenshot: Hier wird von einem Steuerpaket, welches den Pfad zu einer Exceldatei via Paketkonfiguration erhält, ein Kindpaket aufgerufen wobei der Verbindungsmanager zwischen den Paketen übergeben wird.<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/enhanced_2.png" alt="" /><br />
<br\><br />
<strong>Hinweis:</strong> Das Projekt hat derzeit noch den <strong>Alpha-Status</strong> – vom Einsatz in einer Produktivumgebung rate ich also dringend ab! Laut Aussage des Authors scheint es aber stabil zu laufen und dieser freut sich mit Sicherheit über ausgiebiges feedback in Form von Kommentaren oder Anmerkungen. In diesem Sinne: happy testing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/codeplex-perlen-heute-enhanced-ssis-execute-package-task/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Excel und führende Nullen vs. SSIS</title>
		<link>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/excel-und-fuhrende-nullen-vs-ssis/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/excel-und-fuhrende-nullen-vs-ssis/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 08:03:47 +0000</pubDate>
		<dc:creator>Chris Jacob</dc:creator>
				<category><![CDATA[Integration Services 2005]]></category>
		<category><![CDATA[Integration Services 2008]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=79</guid>
		<description><![CDATA[Wer kennt sie nicht: die Problematik der führenden Nullen in Excel. Um beispielsweise Postleitzahlen mit führenden Nullen korrekt darzustellen, bedarf es in aller Regel Einiges an Formatierungsaufwand, da Excel Zahlen gerne als numerischen Wert interpretiert. Befüllt man nun mit den SSIS ein Excel-Ziel, gehen führende Nullen beim ersten Öffnen der Excel-Mappe verloren, ganz gleich ob [...]]]></description>
			<content:encoded><![CDATA[<p>Wer kennt sie nicht: die Problematik der führenden Nullen in Excel. Um beispielsweise Postleitzahlen mit führenden Nullen korrekt darzustellen, bedarf es in aller Regel Einiges an Formatierungsaufwand, da Excel Zahlen gerne als numerischen Wert interpretiert. Befüllt man nun mit den SSIS ein Excel-Ziel, gehen führende Nullen beim ersten Öffnen der Excel-Mappe verloren, ganz gleich ob man z.B. eine Spalte PLZ als Text oder Zahl durchleitet.</p>
<p><span id="more-79"></span><br />
<br\><br />
Abhilfe schafft hier ein kleiner Trick, der in den screenshots unten zu sehen ist. Mittels des Tasks &#8220;Abgeleitete Spalte&#8221; erstellt man eine neue Textspalte, deren Inhalt die Spalte mit den führenden Nullen eingebettet in Hochkommata und ein vorangestelltes Gleichheitszeichen ist (Escape-Sequenz beachten!).<br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/030110_0803_Excelundfhr1.png" alt="" /><br />
<br\><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/030110_0803_Excelundfhr2.png" alt="" /><br />
<br\><br />
Als Resultat interpretiert Excel fortan den Wert in der Spalte als Formel und die führende Null wird korrekt dargestellt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/integration-services-2005/excel-und-fuhrende-nullen-vs-ssis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSAS 2005 MDX Tuning – unnötige MEMBER und fast noch schlimmer: STRTOMEMBER</title>
		<link>http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 16:29:55 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Analysis Services 2005]]></category>
		<category><![CDATA[SQL Server 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/</guid>
		<description><![CDATA[&#8220;Das beste MDX ist das, das man nicht schreibt&#8221; (über den Buschfunk: Mosha Pasumansky)
Aber wer kommt denn auf die Idee, dass dieses Zitat wortwörtlich zu nehmen ist?
Ich sah mich mit einer Kundendimension von 172.000 Kunden konfrontiert, die etwa 200 Vertretern zugeordnet waren. Ergebnis der Abfrage sollten die Kunden sein, die in einem gewissen Monat keine [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Das beste MDX ist das, das man nicht schreibt&#8221; (über den Buschfunk: Mosha Pasumansky)</p>
<p>Aber wer kommt denn auf die Idee, dass dieses Zitat wortwörtlich zu nehmen ist?</p>
<p>Ich sah mich mit einer Kundendimension von 172.000 Kunden konfrontiert, die etwa 200 Vertretern zugeordnet waren. Ergebnis der Abfrage sollten die Kunden sein, die in einem gewissen Monat keine Umsätze, dafür aber im Rest des Jahres Umsätze erzielt hatten.</p>
<p><span id="more-77"></span><br />
<br />
 Übersetzt in den AdventureWorks Cube, wobei der Vertreter hier durch die Dimension &#8220;Produkt&#8221; ersetzt wird, sah die Abfrage zuerst so aus:</p>
<p><span style="font-family: Courier New; color: blue; font-size: 10pt;">WITH<br />
</span></p>
<p><span style="font-family: Courier New;"><span style="font-size: 10pt;"><span style="color: blue;">MEMBER</span><br />
</span><span style="color: #c00000; font-size: 12pt; text-decoration: underline;"><strong><em>UmsatzDezember03</em></strong></span><span style="font-size: 10pt;"><br />
<span style="color: blue;">AS</span><br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">(<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    ,<span style="color: maroon;">STRTOMEMBER</span>(&#8216;[Date].[Calendar].[Month].&amp;[2003]&amp;[12]&#8216;, <span style="color: blue;">CONSTRAINED</span>)<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">)<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SET</span> Kunden <span style="color: blue;">AS</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">EXCEPT</span>(<span style="color: maroon;">EXISTS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">(<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">        ,[Measures].[Internet Sales Amount])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">        ,[Product].[Product Categories].[Category].&amp;[1])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">,<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New;"><span style="font-size: 10pt;">    ,</span><span style="color: #c00000; font-size: 12pt; text-decoration: underline;"><strong><em>UmsatzDezember03</em></strong></span><span style="font-size: 10pt;">))<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">SELECT</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 0,<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    Kunden<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 1 <span style="color: blue;">FROM</span> [Adventure Works]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">WHERE</span> [Date].[Calendar].[Calendar Year].&amp;[2003]<br />
</span><br />
<br\><br />
Um der besseren Lesbarkeit willen erstellte ich das berechnete MEMBER UmsatzDezember03 um das &#8211; zugegeben etwas komplizierte – Kundenset zu filtern.<br />
<br\><br />
Die ursprüngliche Abfrage (nicht das Beispiel hier) benötigte 45 Sekunden, was bei einer so kleinen Dimension von 172.000 Membern nicht akzeptabel war. Query-Tuning war also unumgänglich.<br />
<br\><br />
Nehmen wir uns des Beispiels oben an: Diese Abfrage &#8211; mit <a href="http://cid-74f04d1ea28ece4e.skydrive.live.com/self.aspx/MDXStudio/v0.4.12/MDXStudio2005.zip">&#8220;MDX Studio&#8221;</a> auf dem AdventureWorks Cube ausgeführt &#8211; berechnete 44.240 Zellen und benötigte 2,6 Sekunden für die Ausführung.<br />
<br\><br />
Mosha&#8217;s Befehl zur Sparsamkeit gehorchend, verzichtete ich auf das Hilfsmember und brachte den Ausdruck für UmsatzDezember03 direkt in das Kundenset.</p>
<p><span style="font-family: Courier New; color: blue; font-size: 10pt;">WITH<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SET</span> Customers <span style="color: blue;">AS</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">EXCEPT</span>(<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    <span style="color: maroon;">EXISTS</span>(<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">                ,[Measures].[Internet Sales Amount])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">        ,[Product].[Product Categories].[Category].&amp;[1])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">,<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    ,(<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    ,<span style="color: maroon;">STRTOMEMBER</span>(&#8216;[Date].[Calendar].[Month].&amp;[2003]&amp;[12]&#8216;,<span style="color: blue;"> CONSTRAINED</span>)<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">)))<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">SELECT</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 0,<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    Customers<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 1 <span style="color: blue;">FROM</span> [Adventure Works]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">WHERE</span> [Date].[Calendar].[Calendar Year].&amp;[2003]</span><br />
<br\><br />
Dies führte zu einer Berechnung von nur 7.272 Zellen, benötigte aber immer noch 2,6 Sekunden für die Ausführung. Nachdem ich mir auch das <span style="font-family: Courier New; color: blue; font-size: 10pt;">CONSTRAINED</span> Flag in der <span style="color: maroon;">STRTOMEMBER </span>Funktion erspart hatte, lag die Ausführungszeit bei 0,6 Sekunden.<br />
<br\><br />
Was war passiert? Offensichtlich führte das Einfügen des berechneten Members UmsatzDezember03 dazu, das die Berechnung für den Term <span style="font-family: Courier New;"><span style="font-size: 10pt;"><span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS</span>,</span><span style="color: #c00000; font-size: 12pt; text-decoration: underline;"><strong><em>UmsatzDezember03</em></strong></span><span style="font-size: 10pt;">)</span></span> für <strong>jedes</strong> einzelne Member der Kundendimension ausgeführt wurde – d.h. je mehr Member in der Dimension enthalten sind, desto langsamer wird die Abfrage.<br />
<br\><br />
Darüber hinaus ist festzustellen, dass das CONSTRAINED Flag die Query ebenfalls verlangsamt – was uns zu dem Schluss führt, das Mosha&#8217;s Zitat tatsächlich wortwörtlich zu nehmen ist. Allein das Einsparen der Worte &#8220;MEMBER, AS, STRTOMEMBER und CONSTRAINED&#8221; führt in obigem Beispiel zu einer Beschleunigung der Abfrage von 500% und zu einer 86%-igen Reduktion der berechneten Zellen.<span style="font-family: Courier New; color: blue; font-size: 10pt;"><br />
</span><br />
<br\><br />
In den Analysis Services 2008 tritt dieses Problem nicht mehr auf. &#8220;Hilfsmember&#8221; können hier ohne Scham verwendet werden. Beide auf einem SQL Server 2008 ausgeführten Abfragen berechneten nur die nötigen 7.272 Zellen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

