<?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>ORAYLIS Blog &#187; Daniel Esser</title>
	<atom:link href="http://blog.oraylis.de/author/desser/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.oraylis.de</link>
	<description>ORAYLIS - Einfach mehr Wissen</description>
	<lastBuildDate>Fri, 18 May 2012 09:46:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>SSIS Pattern: Naming Convention Part I</title>
		<link>http://blog.oraylis.de/2012/03/ssis-pattern-naming-convention-part-i/</link>
		<comments>http://blog.oraylis.de/2012/03/ssis-pattern-naming-convention-part-i/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 10:10:15 +0000</pubDate>
		<dc:creator>Daniel Esser</dc:creator>
				<category><![CDATA[MS SSIS]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Design Pattern]]></category>
		<category><![CDATA[ETL]]></category>

		<guid isPermaLink="false">http://blog.oraylis.de/?p=958</guid>
		<description><![CDATA[<p>A naming convention is a convention for naming things. The intent is to allow useful information to be deduced from the names based on regularities. For instance, in Manhattan, streets are named in two different fashions. East-West streets are called &#8220;Streets&#8221; and North-South streets called &#8220;Avenues&#8221;.</p>
<p>First we have to identify which entities have to be named in SSIS:</p>
<ul>
<li>Projects</li>
<li>Packages (filename and identification name)</li>
<li>Configurations</li>
<li>Loggers</li>
<li>Connections</li>
<li>Variables</li>
<li>Control Flow and Data Flow items</li>
</ul>
<p>Secondly it is not important <strong>which </strong>naming convention you use. It is important <strong>that </strong>you use a naming convention. There is a good article about naming conventions on <a href="http://en.wikipedia.org/wiki/Naming_conventions_%28programming%29">Wikipedia</a> you could use for inspiration. The CamelCase naming convention is often used in programming, so I decided to use it for the following examples.</p>
<p>Thirdly we need a clear and intuitive naming definition on <strong>how </strong>to describe the listed entities above. A naming definition of an entity assumes that we know how to describe important properties of the entity. So what are the important properties of the listed entities?</p>
<h4>The Project Name</h4>
<p>The name of the SSIS-Project gives a developer an hint which technical task or problem is solved inside. This name is the key entry point to a technical solution, a name for a jigsaw piece. Is is not best practise to bunch all technical things together. Sketch out the system boundaries and name them. Imagine it is a piece of a jigsaw. What picture (the name) have to be on the piece so you can assign it to the right place in the whole.</p>
<h4>The Package Name</h4>
<p>The package name is related to the given project name. A package is a small piece of the entire project. Without it the entire project can&#8217;t exist.</p>
<p>A package can do many things. It could be a control package, which starts other packages. It could be a package which start dimension or cube processing or it loads data from external or operative data sources into a local database for further processing. We can see that there are at least three different things a package can do: <strong>Control</strong>, <strong>Load </strong>and execute <strong>functional </strong>things like sending emails or starting dimension processing. So it suggests itself to use this information for the package naming definition. For example you could use the following prefixes in the package name:</p>
<ul>
<li><em>Ctrl </em>for packages which controls the execution of other packages</li>
<li><em>Load </em>for packages which loads data</li>
<li><em>Func </em>for packages which do some functional things like sending mails etc. pp.</li>
</ul>
<p>Based on this we can go further. For <em>Ctrl </em>and <em>Func</em> packages it is obvious how to name them further. The simple questions are: What is the package to be controlled? What functional thing the package will do? Some examples:</p>
<ul>
<li><em>CtrlMaster </em>- A master control package for the whole project</li>
<li><em>CtrlCubeProcessing </em>- A package which calls other packages to process dimensions and cubes in a non default manner</li>
<li><em>FuncSendSuccMail </em>- Send a success mail to some people after processing cubes</li>
<li><em>FuncValidateMailAdresses </em>- A package which validates a table with mail addresses. It marks which are correct and which not.</li>
</ul>
<p>A load package is somewhat specific. Mostly there is at least one source and one target. So load packages can operate on different databases, tables, schemas etc. pp. The package name should reflect that fact. Here at ORAYLIS we have a process model on how to load data for Datawarehousing. We arrange the whole loading process into three layers: Extraction-Layer, Working-Layer and Frontroom. The Extraction-Layer hold the raw data from external and operative data sources. You could think of it as a one-to-one copy in a relational database or the interface to the outside world. In the Working-Layer we put data together (joining tables, calculating new columns, renaming, data cleansing etc.). The Frontroom-Layer is the actual Datawarehouse. So we have three important layers for loading a Datawarehouse. This could lead us to the following naming definition for Load-Packages.</p>
<ul>
<li><em>LoadExtract </em>- A package which loads data from an operative or external data source</li>
<li><em>LoadWork </em>- A package which modifies the loaded data from the Extraction-Layer</li>
<li><em>LoadFront </em>- A package which fills the Datawarehouse with data from the Work or Extraction-Layer</li>
</ul>
<p>It is possible to have more than one Extraction-, Work- or Frontroom-Layer. Simply add the name of the layer (or other important information) at the end of the package name. For example <em>LoadFrontSalesDimCustomer </em>if the package fills the <em>Customer Dimension</em> for the <em>Sales Datawarehouse</em> which is stored in the Frontroom-Layer. The final naming definition for <em>Load</em>-Packages could be</p>
<p style="text-align: center"><em>&#8220;Load&#8221;</em> {Logical Layer} {Database Name or abbreviation} {Tablename/Dimension/Fact}</p>
<h4>Connections</h4>
<p>Based on the naming conventions above for packages it is best practice to name a connection based on a logical name rather a database name or a server name. A database name can be volatile or meaningless like EGH275. So calling a connection DWH123.EGH275 is either wrong after the Go-live because the server name changed or could be meaningless like EGH275. A logical server name could be DWH and a logical database could be <em>Frontroom</em> which leads to <em>DWHFrontoom</em> or DWHWork.</p>
<p style="text-align: center">{<em>Logical Server Name</em>} {<em>Layer</em>}</p>
<h4 style="text-align: left">Variables</h4>
<p>Variables in SSIS can be described with a name, a name space and a context. The context is the world were the variable exists in, typically an SSIS container. So variables are context specific or global. The default name space for a variable is called <em>User</em>.</p>
<p>I use the name space to describe the main purpose for using the variable. Is it a variable to override connection strings? Is it a counter in an For-Each-Loop-Container? I found at least three name spaces:</p>
<ul>
<li><em>User &#8211; </em>holds mostly context specific variables</li>
<li><em>Config &#8211; </em>holds variables which overloads package or task properties and is more global</li>
<li><em>Result</em> &#8211; holds variables with information for further processing inside or outside the package. These variables are mostly global.</li>
</ul>
<p>The variable name is highly specific. So the only advice I can give is to use lowerCamelCase.</p>
<h4>Control and Data Flow Items</h4>
<p>The name of a task or container is comparable with the name of a function or procedure. For example the function name <em>Math.Add</em> imply that it can add two numbers. A Task name should do also.</p>
<p>I often use the <em>WhoN&#8217;How-Where-What</em>-Pattern for Data Flow Items. For example a data source (Who?) which loads accounting periods (What?) from the Work-Layer (Where?) in the ABCD-Table (Where?) is called:</p>
<p style="text-align: center"><em><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/SrcExample.png"><img class="aligncenter size-full wp-image-968" src="http://blog.oraylis.de/wp-content/uploads/2011/02/SrcExample.png" alt="" width="254" height="44" /></a><br />
</em></p>
<p style="text-align: left">Using <em>CamelCase </em>here would lead us to <em>SrcWorkAbcdAccountingPeriod</em> but this is too illegible. See here another example. A Lookup-Component. Proof it &#8230; what is done here?</p>
<p style="text-align: center"><em><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/LookupExample.png"><img class="aligncenter size-full wp-image-969" src="http://blog.oraylis.de/wp-content/uploads/2011/02/LookupExample.png" alt="" width="422" height="44" /></a><br />
</em></p>
<p style="text-align: left">This name gives us the following information: A <strong>full </strong>cache <strong>lookup </strong>onto the <strong>ShippingAddress table </strong>in the <strong>Extract-Layer</strong> with the <strong>IDShipAddr key column</strong> which returns the <strong>StrName column</strong> named as <strong>Street</strong>. It is very long eeh? Of course it is, but having a meaningful name is better than having a non-meaningful name. Every time I see packages without naming conventions the first thing I do is to rename the items inside to get the big picture.</p>
<h4 style="text-align: left">Conclusion</h4>
<p style="text-align: left">In this article I covered naming conventions for control and data flow items as well as for packages, connections and variables. Feel free to make comments and suggestions on how to name things and please keep in mind: It is not important <strong>which </strong>naming convention you use. It is important <strong>that </strong>you use a naming convention.</p>
<p style="text-align: left">
<div style="display:block"><small><em>by Daniel Esser <ul class="addtoany_list"><li><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.oraylis.de%2F2012%2F03%2Fssis-pattern-naming-convention-part-i%2F&amp;linkname=SSIS%20Pattern%3A%20Naming%20Convention%20Part%20I"><img src="http://blog.oraylis.de/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a></li></ul></em></small></div>]]></description>
			<content:encoded><![CDATA[<p>A naming convention is a convention for naming things. The intent is to allow useful information to be deduced from the names based on regularities. For instance, in Manhattan, streets are named in two different fashions. East-West streets are called &#8220;Streets&#8221; and North-South streets called &#8220;Avenues&#8221;.</p>
<p>First we have to identify which entities have to be named in SSIS:</p>
<ul>
<li>Projects</li>
<li>Packages (filename and identification name)</li>
<li>Configurations</li>
<li>Loggers</li>
<li>Connections</li>
<li>Variables</li>
<li>Control Flow and Data Flow items</li>
</ul>
<p>Secondly it is not important <strong>which </strong>naming convention you use. It is important <strong>that </strong>you use a naming convention. There is a good article about naming conventions on <a href="http://en.wikipedia.org/wiki/Naming_conventions_%28programming%29">Wikipedia</a> you could use for inspiration. The CamelCase naming convention is often used in programming, so I decided to use it for the following examples.</p>
<p>Thirdly we need a clear and intuitive naming definition on <strong>how </strong>to describe the listed entities above. A naming definition of an entity assumes that we know how to describe important properties of the entity. So what are the important properties of the listed entities?</p>
<h4>The Project Name</h4>
<p>The name of the SSIS-Project gives a developer an hint which technical task or problem is solved inside. This name is the key entry point to a technical solution, a name for a jigsaw piece. Is is not best practise to bunch all technical things together. Sketch out the system boundaries and name them. Imagine it is a piece of a jigsaw. What picture (the name) have to be on the piece so you can assign it to the right place in the whole.</p>
<h4>The Package Name</h4>
<p>The package name is related to the given project name. A package is a small piece of the entire project. Without it the entire project can&#8217;t exist.</p>
<p>A package can do many things. It could be a control package, which starts other packages. It could be a package which start dimension or cube processing or it loads data from external or operative data sources into a local database for further processing. We can see that there are at least three different things a package can do: <strong>Control</strong>, <strong>Load </strong>and execute <strong>functional </strong>things like sending emails or starting dimension processing. So it suggests itself to use this information for the package naming definition. For example you could use the following prefixes in the package name:</p>
<ul>
<li><em>Ctrl </em>for packages which controls the execution of other packages</li>
<li><em>Load </em>for packages which loads data</li>
<li><em>Func </em>for packages which do some functional things like sending mails etc. pp.</li>
</ul>
<p>Based on this we can go further. For <em>Ctrl </em>and <em>Func</em> packages it is obvious how to name them further. The simple questions are: What is the package to be controlled? What functional thing the package will do? Some examples:</p>
<ul>
<li><em>CtrlMaster </em>- A master control package for the whole project</li>
<li><em>CtrlCubeProcessing </em>- A package which calls other packages to process dimensions and cubes in a non default manner</li>
<li><em>FuncSendSuccMail </em>- Send a success mail to some people after processing cubes</li>
<li><em>FuncValidateMailAdresses </em>- A package which validates a table with mail addresses. It marks which are correct and which not.</li>
</ul>
<p>A load package is somewhat specific. Mostly there is at least one source and one target. So load packages can operate on different databases, tables, schemas etc. pp. The package name should reflect that fact. Here at ORAYLIS we have a process model on how to load data for Datawarehousing. We arrange the whole loading process into three layers: Extraction-Layer, Working-Layer and Frontroom. The Extraction-Layer hold the raw data from external and operative data sources. You could think of it as a one-to-one copy in a relational database or the interface to the outside world. In the Working-Layer we put data together (joining tables, calculating new columns, renaming, data cleansing etc.). The Frontroom-Layer is the actual Datawarehouse. So we have three important layers for loading a Datawarehouse. This could lead us to the following naming definition for Load-Packages.</p>
<ul>
<li><em>LoadExtract </em>- A package which loads data from an operative or external data source</li>
<li><em>LoadWork </em>- A package which modifies the loaded data from the Extraction-Layer</li>
<li><em>LoadFront </em>- A package which fills the Datawarehouse with data from the Work or Extraction-Layer</li>
</ul>
<p>It is possible to have more than one Extraction-, Work- or Frontroom-Layer. Simply add the name of the layer (or other important information) at the end of the package name. For example <em>LoadFrontSalesDimCustomer </em>if the package fills the <em>Customer Dimension</em> for the <em>Sales Datawarehouse</em> which is stored in the Frontroom-Layer. The final naming definition for <em>Load</em>-Packages could be</p>
<p style="text-align: center"><em>&#8220;Load&#8221;</em> {Logical Layer} {Database Name or abbreviation} {Tablename/Dimension/Fact}</p>
<h4>Connections</h4>
<p>Based on the naming conventions above for packages it is best practice to name a connection based on a logical name rather a database name or a server name. A database name can be volatile or meaningless like EGH275. So calling a connection DWH123.EGH275 is either wrong after the Go-live because the server name changed or could be meaningless like EGH275. A logical server name could be DWH and a logical database could be <em>Frontroom</em> which leads to <em>DWHFrontoom</em> or DWHWork.</p>
<p style="text-align: center">{<em>Logical Server Name</em>} {<em>Layer</em>}</p>
<h4 style="text-align: left">Variables</h4>
<p>Variables in SSIS can be described with a name, a name space and a context. The context is the world were the variable exists in, typically an SSIS container. So variables are context specific or global. The default name space for a variable is called <em>User</em>.</p>
<p>I use the name space to describe the main purpose for using the variable. Is it a variable to override connection strings? Is it a counter in an For-Each-Loop-Container? I found at least three name spaces:</p>
<ul>
<li><em>User &#8211; </em>holds mostly context specific variables</li>
<li><em>Config &#8211; </em>holds variables which overloads package or task properties and is more global</li>
<li><em>Result</em> &#8211; holds variables with information for further processing inside or outside the package. These variables are mostly global.</li>
</ul>
<p>The variable name is highly specific. So the only advice I can give is to use lowerCamelCase.</p>
<h4>Control and Data Flow Items</h4>
<p>The name of a task or container is comparable with the name of a function or procedure. For example the function name <em>Math.Add</em> imply that it can add two numbers. A Task name should do also.</p>
<p>I often use the <em>WhoN&#8217;How-Where-What</em>-Pattern for Data Flow Items. For example a data source (Who?) which loads accounting periods (What?) from the Work-Layer (Where?) in the ABCD-Table (Where?) is called:</p>
<p style="text-align: center"><em><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/SrcExample.png"><img class="aligncenter size-full wp-image-968" src="http://blog.oraylis.de/wp-content/uploads/2011/02/SrcExample.png" alt="" width="254" height="44" /></a><br />
</em></p>
<p style="text-align: left">Using <em>CamelCase </em>here would lead us to <em>SrcWorkAbcdAccountingPeriod</em> but this is too illegible. See here another example. A Lookup-Component. Proof it &#8230; what is done here?</p>
<p style="text-align: center"><em><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/LookupExample.png"><img class="aligncenter size-full wp-image-969" src="http://blog.oraylis.de/wp-content/uploads/2011/02/LookupExample.png" alt="" width="422" height="44" /></a><br />
</em></p>
<p style="text-align: left">This name gives us the following information: A <strong>full </strong>cache <strong>lookup </strong>onto the <strong>ShippingAddress table </strong>in the <strong>Extract-Layer</strong> with the <strong>IDShipAddr key column</strong> which returns the <strong>StrName column</strong> named as <strong>Street</strong>. It is very long eeh? Of course it is, but having a meaningful name is better than having a non-meaningful name. Every time I see packages without naming conventions the first thing I do is to rename the items inside to get the big picture.</p>
<h4 style="text-align: left">Conclusion</h4>
<p style="text-align: left">In this article I covered naming conventions for control and data flow items as well as for packages, connections and variables. Feel free to make comments and suggestions on how to name things and please keep in mind: It is not important <strong>which </strong>naming convention you use. It is important <strong>that </strong>you use a naming convention.</p>
<p style="text-align: left">
]]></content:encoded>
			<wfw:commentRss>http://blog.oraylis.de/2012/03/ssis-pattern-naming-convention-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Templating-Mechanismus für Integration-Service-Pakete (Update SQL Server 2012)</title>
		<link>http://blog.oraylis.de/2012/03/templating-mechanismus-fr-integration-service-pakete/</link>
		<comments>http://blog.oraylis.de/2012/03/templating-mechanismus-fr-integration-service-pakete/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 09:00:31 +0000</pubDate>
		<dc:creator>Daniel Esser</dc:creator>
				<category><![CDATA[Microsoft BI]]></category>
		<category><![CDATA[MS SSIS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Test Tools]]></category>

		<guid isPermaLink="false">http://blog.oraylis.de/?p=865</guid>
		<description><![CDATA[<h5><span style="text-decoration: underline">Update für SQL Server 2012 (16.03.2012)</span></h5>
<p>Die RTM Version des SQL Server 2012 ist gerade draußen und einige Fragen sich bereits ob das generieren von Pakten unter der Version 2012 immer noch funktioniert, schließlich hat sich das Paketformat drastisch verändert.</p>
<p>Die Antwort lautet ja. Allerdings sind die Integration Service Assemblies auf die CLR Version 4 angehoben worden. Solltet Ihr nun versuchen das ManagedDTS Assembly zu laden bekommt ihr folgende Fehlermeldung.</p>
<p style="text-align: center"><em>This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. (Exception from HRESULT: 0x8013101B)</em></p>
<p>Dies liegt daran, dass die Powershell 2.0 keine CLR 4 Assemblies laden kann (nur bis CLR 3.5). Glücklicherweise gibt es schon die PowerShell 3.0 CTP 2 oder richtiger das <a href="http://www.microsoft.com/download/en/details.aspx?id=27548" target="_blank">Windows Management Framework 3.0 CTP 2</a> welches PowerShell 3.0 beinhaltet. Mit PowerShell 3.0 ist es nun wieder möglich die entsprechenden Assemblies zu laden. Die Assemblies findet Ihr wie gewohnt unter:</p>
<p style="text-align: center"><em>C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies</em></p>
<h5>Einführung</h5>
<p>Es gibt vielerlei Gründe dafür ein SSIS-Template-Paket zu erstellen. In der Regel möchte man die Konfiguration über die Vielzahl der Paket in einem Projekt homogen halten. Heterogenität in der Paketkonfiguration erhöht die Fehleranfälligkeit während der Bereitstellungsphase insgesamt. Zwar gibt es die Möglichkeit der Vererbung der Konfiguration für Unterpakete, allerdings führt das für den IS-Entwickler dazu, dass Pakete nicht mehr einzeln zu starten sind, da diesen Paketen die vererbte Konfiguration des Elternpakts fehlt. Diese Einschränkung ist für die Entwicklung nicht hinnehmbar.</p>
<p>Um diese Einschränkung zu umgehen, muss jedes Paket einzeln Konfiguriert werden. Diese Arbeit manuell zu machen erhöht wieder die Fehleeanfälligkeit für die Bereitstellungsphase. So liegt der logische Schluss der Automatisierung recht nahe.</p>
<p>Nun gibt es unzählige Möglichkeiten IS-Pakete automatisiert anzupassen. Eine Möglichkeit wäre die Pakete durch einen XSLT-Prozessor zu jagen, die für die richtig Konfiguration sorgt. Das hätte den Charm, dass man für verschiedene Bereitstelllungszenarien verschiedene XSLT-Stylesheets schreiben könnte, die die jeweilige Konfiguration für das entsprechende Endsystem berücksichtigt. Der Nachteil dieser Variante ist, dass das KnowHow für XSLT vorhanden sein muss. Außerdem geht XSLT nicht leicht von der Hand.</p>
<p>Ein andere Variante wäre ein .NET-Applikation zu entwerfen, welche mitteln des IS-Objektmodell die entsprechenden Pakte anpasst oder generiert. Der Nachteil hierbei wäre die fehlende Flexibilität während der Entwicklung. Schnelle Änderungen setzen eine Ressource mit C#-Kenntnissen und Visual Studio voraus.</p>
<p>Eine ähnlicher aber flexiblerer Ansatz wäre eine Skript-Sprache zu verwenden mit Zugang zur .NET-Welt. Die Möglichkeiten sind auch hier wieder vielfältig. Hier wären zu nennen: Visual Basic, PowerShell und Iron Python. Welche Skript-Sprache man verwendet ist eher eine Geschmackssache. Da ich das Erweitern von IS-Paketen um eine einheitliche Paketkonfiguration eher in der Bereitstellung verorten würde, würde ich PowerShell (wegen der Nähe zur Administration) den Vorzug geben.</p>
<h5>Grundgerüst</h5>
<p>Die erste Hürde, die es zu meisten gilt ist von recht langweiliger Natur. Standardmäßig können PowerShell-Skripte nicht direkt ausgeführt werden. Wenn man sich die Mächtigkeit der PoweShell bewusst macht, ist das verständlich.</p>
<p>Es gibt zwei Wege dieses Hürde zu nehmen. Zum einen können wir die Sicherheitsmaßnahmen für PowerShell-Skripte herunterfahren. Für eine Produktionsumgebung ist das <strong>nicht</strong> zu empfehlen, zu Entwicklungszwecken aber legitim. Mit folgendem Kommando wird die Sicherheitseinstellung ausgeschaltet.</p>
<p><span style="font-family: Courier New"><span style="color: #9b00d3">Set-ExecutionPolicy</span> Unrestricted</span></p>
<p>Für eine Produktionsumgebung müsste das Skript signiert werden und eine Vertrauensstellung dem Eigentümer gegenüber eingerichtet werden. Weitere Informationen hierzu finden sich hier:</p>
<ul>
<li><a title="http://www.scriptinganswers.com/essentials/index.php/2008/02/21/how-do-i-sign-a-windows-powershell-script/" href="http://www.scriptinganswers.com/essentials/index.php/2008/02/21/how-do-i-sign-a-windows-powershell-script/">http://www.scriptinganswers.com/essentials/index.php/2008/02/21/how-do-i-sign-a-windows-powershell-script/</a></li>
</ul>
<p>Der nächste Schritt wäre PowerShell mit SSIS zu verheiraten. Dazu müssen Assemblies des SQL Servers geladen werden. Im Fall des SQL Server 2008 befinden sich diese Dateien im Verzeichnis <span style="font-family: Courier New">C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies</span>.</p>
<p><span style="font-family: Courier New">[Reflection.Assembly]::LoadFile(<span style="color: #cccccc">&#8220;&#8230;\Microsoft.SqlServer.DTSPipelineWrap.dll&#8221;</span>)[Reflection.Assembly]::LoadFile(<span style="color: #cccccc">&#8220;&#8230;\Microsoft.SQLServer.ManagedDTS.dll&#8221;</span>)</span></p>
<p>Nach diesem Schritt stehen einem alle Objekte des SSIS-Objektsmodells zur Verfügung. Der nächste Schritt ist nun sich eine SSIS-Applikationskontext zu besorgen, ein Paket zu erstellen bzw. zu öffnen, Änderungen vorzunehmen und diese wieder abzuspeichern. Hier ein Beispiel für ein Grundgerüst:</p>
<p>&nbsp;</p>
<p><span style="font-family: Courier New"><span style="color: #008040"># SSIS-Kontext erstellen</span><br />
<strong>$context</strong> = <span style="color: #9b00d3">new-object</span> Microsoft.SqlServer.Dts.Runtime.Application </span></p>
<p><span style="font-family: Courier New"><span style="color: #008040"># Neues Paket erstellen<br />
</span><strong>$package</strong> = <span style="color: #9b00d3">new-object</span> Microsoft.SqlServer.Dts.Runtime.Package </span></p>
<p><span style="font-family: Courier New"><span style="color: #008040"># Paket nach eigenen Wünschen anpassen<br />
</span><br />
<span style="color: #008040"># Aufräumen</span><br />
[System.Runtime.Interopservices.Marshal]::ReleaseComObject(<strong>$package</strong>)[System.Runtime.Interopservices.Marshal]::ReleaseComObject(<strong>$context</strong>) </span></p>
<p><span style="font-family: Courier New"><span style="color: #9b00d3">Remove-Variable</span> context<br />
<span style="color: #9b00d3">Remove-Variable</span> package</span></p>
<p>Soll ein bereits vorhandenes Paket geöffnet werden müsste das Grundgerüst entsprechend angepasst werden:</p>
<p><span style="font-family: Courier New"><strong>$context</strong>.LoadPackage<span style="color: #cccccc">(&#8220;C:\TestPackage.dtsx&#8221;</span>, <strong>$null</strong>, <strong>$false</strong>)</span></p>
<h5>Variablen erstellen und/oder anpassen</h5>
<p>Bei der Homogenisierung der Paketkonfiguration werden Variablen benötigt. Zum Beispiel können Variablen dazu verwendet werden bestimmte Connections über Expressions zu Parametrisieren. Hier ein einfaches Beispiel um dem Paket Variablen mit zu geben. Diese Variablen werden später mittels Expressions an eine Connection weitergegeben. Über diese Connection werden dann alle benötigten weiteren Connections und Variablen geladen.</p>
<p><span style="font-family: Courier New"><strong>$var</strong> = <strong>$package</strong>.Variables.Add(<span style="color: #cccccc">&#8220;AdminDBCatalog&#8221;</span>, <strong>$false</strong>, <span style="color: #cccccc">&#8220;Config&#8221;</span>, <span style="color: #cccccc">&#8220;AdminDB&#8221;</span>)<br />
<strong>$var</strong> = <strong>$package</strong>.Variables.Add(<span style="color: #cccccc">&#8220;AdminDBHostename&#8221;</span>, <strong>$false</strong>, <span style="color: #cccccc">&#8220;Config&#8221;</span>, <span style="color: #cccccc">&#8220;HOSTNAME&#8221;</span>)</span></p>
<h5>Paketkonfiguration einschalten</h5>
<p>Wie die Connections und die Variablen ist auch die Paketkonfiguration über das Objekt-Modell zu erreichen. Der Einfachheit halber verzichte ich an dieser Stelle darauf zu überprüfen ob die Konfiguration bereits existiert. Auf das grundlegende Prinzip dabei gehe ich bei der Erstellung der Connections im nächsten Abschnitt ein.</p>
<p>Im folgenden erstelle ich eine Paketkonfiguration welche einen Katalog- und Hostnamen aus einer Environmentvariable läd. Später wird eine Connection dann mit den Inhalten der Variablen parametrisiert.</p>
<p><span style="font-family: Courier New"><span style="color: #008000">#Sicherstellen, dass die Paket-Konfiguration eingeschaltet ist<br />
</span><strong>$package</strong>.EnableConfigurations = <strong>$true</strong> </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Katalog aus Envrironment-Variable laden </span></span><span style="font-family: Courier New"><br />
<strong>$config </strong>= <strong>$package</strong>.Configurations.Add()<br />
<strong>$config</strong>.Name = <span style="color: #cccccc">&#8220;AdminDBCatalog&#8221;<br />
</span></span><span style="font-family: Courier New"><strong>$config</strong>.ConfigurationType = <span style="color: #ffc000">2</span><br />
<strong>$config</strong>.ConfigurationString = </span><span style="font-family: Courier New"><span style="color: #cccccc">&#8220;AdminDBCatalog&#8221;<br />
</span><strong>$config</strong>.PackagePath = </span><span style="font-family: Courier New;color: #cccccc">&#8220;\Package.Variables[Config::AdminDBHostname].Properties[Value]&#8221; </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Katalog aus Envrironment-Variable laden<br />
</span></span><strong><span style="font-family: Courier New">$config</span></strong><span style="font-family: Courier New"> = <strong>$package</strong>.Configurations.Add()<br />
<strong>$config</strong>.Name = <span style="color: #cccccc">&#8220;AdminDBHostname&#8221;</span><br />
</span><span style="font-family: Courier New"><strong>$config</strong>.ConfigurationType = <span style="color: #ffc000">2</span><br />
$config.ConfigurationString = </span><span style="font-family: Courier New"><span style="color: #cccccc">&#8220;AdminDBHostname&#8221;<br />
</span>$config.PackagePath = </span><span style="color: #cccccc"><span style="font-family: Courier New">&#8220;\Package.Variables[Config::AdminDBCatalog].Properties[Value]&#8220;</span> </span></p>
<h5>Connections erstellen oder anpassen</h5>
<p>Wesentlicher Bestandteil einer Connection ist der Connection-String und der Connection-Type. Folgendes Beispiel zeigt die Erstellung einer einfachen OLEDB-Connection:</p>
<p><span style="font-family: Courier New"><strong>$conMgr</strong> = <strong>$package</strong>.Connections.Add(<span style="color: #cccccc">&#8220;OLEDB&#8221;</span>)<br />
<strong>$conMgr</strong>.Name = <span style="color: #cccccc">&#8220;AdminDB Connection&#8221;</span><br />
<strong>$conMgr</strong>.ConnectionString = <span style="color: #cccccc">&#8220;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AdminDB;Data Source=HOSTNAME;Auto Translate=False;&#8221;</span></span></p>
<p>Den Connection String bekommt man entweder über der Database Explorer des VS, mit dem SSIS-Designer oder von <a title="http://www.connectionstrings.com/" href="http://www.connectionstrings.com/">http://www.connectionstrings.com/</a>. Den Connection Type könnt ihr mit folgendem Befehl ermitteln:</p>
<p><span style="font-family: Courier New"><strong>$context</strong>.ConnectionInfos <span style="color: #9b00d3">|</span> <span style="color: #0000ff">select</span> ConnectionType<br />
</span><br />
<span style="font-family: Courier New">ConnectionType<br />
&#8212;&#8212;&#8212;&#8212;&#8211;<br />
ODBC<br />
FLATFILE<br />
OLEDB<br />
MULTIFILE<br />
MSOLAP100<br />
HTTP<br />
FILE<br />
ADO.NET<br />
FTP<br />
ADO<br />
MULTIFLATFILE<br />
EXCEL<br />
SQLMOBILE<br />
CACHE<br />
MSMQ<br />
SMTP<br />
WMI<br />
SMOServer</span></p>
<p>In der Regel wäre es für unser Vorhaben aber besser wenn auf das Vorhandensein der Connection geprüft und diese ggf. angepasst würde. Prüfen kann man diese wie folgt:</p>
<p><span style="font-family: Courier New"><strong>$ErrorActionPreference</strong> = <span style="color: #cccccc">&#8220;SilentlyContinue&#8221; </span><br />
<strong>$connectionName</strong> = <span style="color: #cccccc">&#8220;AdminDB Connection&#8221;</span><br />
<strong>$conMgr</strong> =<strong> $package</strong>.Connections.Item(<strong>$connectionName</strong>) </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Im Fehlerfall Connection neu anlegen</span><br />
<span style="color: #0000ff">if</span> (<strong>!$?</strong>) {<br />
<strong> $conMgr</strong> = <strong>$package</strong>.Connections.Add(<span style="color: #cccccc">&#8220;OLEDB&#8221;</span>)<br />
<strong> $conMgr</strong>.Name = <strong>$connectionName</strong><br />
}<br />
</span><span style="color: #008000"><br />
<span style="font-family: Courier New"># Connections String setzen<br />
</span></span><span style="font-family: Courier New"><strong>$conMgr</strong>.ConnectionString = <span style="color: #cccccc">&#8220;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AdminDB;Data Source=<span style="color: #ff0000">ANDERESOURCE</span>;Auto Translate=False;&#8221;</span></span></p>
<p><span style="font-family: Courier New"><span style="font-family: Verdana">Diese Technik stellt sicher, dass die Connection angelegt wird oder wenn bereits vorhanden, angepasst wird. Im zweiten Schritt wird die Connection so mit Expressions parametrisiert, dass die Connection dynamisch von den beiden Enronmentvariablen AdminDBCatalog und AdminDBHost abhängt.</span> </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Connection an die Paketkonfiguration koppeln</span><br />
<strong>$conMgr</strong>.SetExpression(<span style="color: #cccccc">&#8220;InitialCatalog&#8221;</span>, <span style="color: #cccccc">&#8220;@[Config::AdminDBCatalog]&#8220;</span>)<br />
<strong>$conMgr</strong>.SetExpression(<span style="color: #cccccc">&#8220;ServerName&#8221;</span>, <span style="color: #cccccc">&#8220;@[Config::AdminDBHostname]&#8220;</span>)</span></p>
<h5>Speichern des Pakets</h5>
<p>Gespeichert werden kann das Paket mit folgendem Kommando:</p>
<p><span style="font-family: Courier New"><strong>$context</strong>.SaveToXml(<span style="color: #cccccc">&#8220;C:\TestPaket.dtsx&#8221;</span>, <strong>$null</strong>)</span></p>
<h5>Fazit und Ausblick</h5>
<p>Im weiteren Verlauf wäre es wohl Ratsam weitere Fehler abzufangen. Des weiteren müssten weitere Variablen und Connections hinzugefügt werden, die man über eine Konfigurationsdatenbank konfigurieren will. Zum Schluss müsste noch die Paketkonfiguration angepasst werden, so dass weitere Inhalte aus der Konfigurationsdatenbank in Variablen geladen werden.</p>
<p>Wie jedoch zu sehen ist kann man mit PoweShell-Skripten und relativ wenigen Zeilen einen kleinen IS-Paket-Generator schreiben der auch noch leicht zu verstehen und zu erweitern ist.</p>
<p>Die Arbeit für solch ein Skript hat man genau einmal. Sich bei jeder Änderung der Konfiguration oder der Implementierung neuer Pakete durch die Dialoge der Paketkonfiguration zu klicken ist recht mühsam, Fehleranfällig und zeitverschwenderisch.</p>
<div style="display:block"><small><em>by Daniel Esser <ul class="addtoany_list"><li><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.oraylis.de%2F2012%2F03%2Ftemplating-mechanismus-fr-integration-service-pakete%2F&amp;linkname=Templating-Mechanismus%20f%C3%BCr%20Integration-Service-Pakete%20%28Update%20SQL%20Server%202012%29"><img src="http://blog.oraylis.de/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a></li></ul></em></small></div>]]></description>
			<content:encoded><![CDATA[<h5><span style="text-decoration: underline">Update für SQL Server 2012 (16.03.2012)</span></h5>
<p>Die RTM Version des SQL Server 2012 ist gerade draußen und einige Fragen sich bereits ob das generieren von Pakten unter der Version 2012 immer noch funktioniert, schließlich hat sich das Paketformat drastisch verändert.</p>
<p>Die Antwort lautet ja. Allerdings sind die Integration Service Assemblies auf die CLR Version 4 angehoben worden. Solltet Ihr nun versuchen das ManagedDTS Assembly zu laden bekommt ihr folgende Fehlermeldung.</p>
<p style="text-align: center"><em>This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. (Exception from HRESULT: 0x8013101B)</em></p>
<p>Dies liegt daran, dass die Powershell 2.0 keine CLR 4 Assemblies laden kann (nur bis CLR 3.5). Glücklicherweise gibt es schon die PowerShell 3.0 CTP 2 oder richtiger das <a href="http://www.microsoft.com/download/en/details.aspx?id=27548" target="_blank">Windows Management Framework 3.0 CTP 2</a> welches PowerShell 3.0 beinhaltet. Mit PowerShell 3.0 ist es nun wieder möglich die entsprechenden Assemblies zu laden. Die Assemblies findet Ihr wie gewohnt unter:</p>
<p style="text-align: center"><em>C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies</em></p>
<h5>Einführung</h5>
<p>Es gibt vielerlei Gründe dafür ein SSIS-Template-Paket zu erstellen. In der Regel möchte man die Konfiguration über die Vielzahl der Paket in einem Projekt homogen halten. Heterogenität in der Paketkonfiguration erhöht die Fehleranfälligkeit während der Bereitstellungsphase insgesamt. Zwar gibt es die Möglichkeit der Vererbung der Konfiguration für Unterpakete, allerdings führt das für den IS-Entwickler dazu, dass Pakete nicht mehr einzeln zu starten sind, da diesen Paketen die vererbte Konfiguration des Elternpakts fehlt. Diese Einschränkung ist für die Entwicklung nicht hinnehmbar.</p>
<p>Um diese Einschränkung zu umgehen, muss jedes Paket einzeln Konfiguriert werden. Diese Arbeit manuell zu machen erhöht wieder die Fehleeanfälligkeit für die Bereitstellungsphase. So liegt der logische Schluss der Automatisierung recht nahe.</p>
<p>Nun gibt es unzählige Möglichkeiten IS-Pakete automatisiert anzupassen. Eine Möglichkeit wäre die Pakete durch einen XSLT-Prozessor zu jagen, die für die richtig Konfiguration sorgt. Das hätte den Charm, dass man für verschiedene Bereitstelllungszenarien verschiedene XSLT-Stylesheets schreiben könnte, die die jeweilige Konfiguration für das entsprechende Endsystem berücksichtigt. Der Nachteil dieser Variante ist, dass das KnowHow für XSLT vorhanden sein muss. Außerdem geht XSLT nicht leicht von der Hand.</p>
<p>Ein andere Variante wäre ein .NET-Applikation zu entwerfen, welche mitteln des IS-Objektmodell die entsprechenden Pakte anpasst oder generiert. Der Nachteil hierbei wäre die fehlende Flexibilität während der Entwicklung. Schnelle Änderungen setzen eine Ressource mit C#-Kenntnissen und Visual Studio voraus.</p>
<p>Eine ähnlicher aber flexiblerer Ansatz wäre eine Skript-Sprache zu verwenden mit Zugang zur .NET-Welt. Die Möglichkeiten sind auch hier wieder vielfältig. Hier wären zu nennen: Visual Basic, PowerShell und Iron Python. Welche Skript-Sprache man verwendet ist eher eine Geschmackssache. Da ich das Erweitern von IS-Paketen um eine einheitliche Paketkonfiguration eher in der Bereitstellung verorten würde, würde ich PowerShell (wegen der Nähe zur Administration) den Vorzug geben.</p>
<h5>Grundgerüst</h5>
<p>Die erste Hürde, die es zu meisten gilt ist von recht langweiliger Natur. Standardmäßig können PowerShell-Skripte nicht direkt ausgeführt werden. Wenn man sich die Mächtigkeit der PoweShell bewusst macht, ist das verständlich.</p>
<p>Es gibt zwei Wege dieses Hürde zu nehmen. Zum einen können wir die Sicherheitsmaßnahmen für PowerShell-Skripte herunterfahren. Für eine Produktionsumgebung ist das <strong>nicht</strong> zu empfehlen, zu Entwicklungszwecken aber legitim. Mit folgendem Kommando wird die Sicherheitseinstellung ausgeschaltet.</p>
<p><span style="font-family: Courier New"><span style="color: #9b00d3">Set-ExecutionPolicy</span> Unrestricted</span></p>
<p>Für eine Produktionsumgebung müsste das Skript signiert werden und eine Vertrauensstellung dem Eigentümer gegenüber eingerichtet werden. Weitere Informationen hierzu finden sich hier:</p>
<ul>
<li><a title="http://www.scriptinganswers.com/essentials/index.php/2008/02/21/how-do-i-sign-a-windows-powershell-script/" href="http://www.scriptinganswers.com/essentials/index.php/2008/02/21/how-do-i-sign-a-windows-powershell-script/">http://www.scriptinganswers.com/essentials/index.php/2008/02/21/how-do-i-sign-a-windows-powershell-script/</a></li>
</ul>
<p>Der nächste Schritt wäre PowerShell mit SSIS zu verheiraten. Dazu müssen Assemblies des SQL Servers geladen werden. Im Fall des SQL Server 2008 befinden sich diese Dateien im Verzeichnis <span style="font-family: Courier New">C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies</span>.</p>
<p><span style="font-family: Courier New">[Reflection.Assembly]::LoadFile(<span style="color: #cccccc">&#8220;&#8230;\Microsoft.SqlServer.DTSPipelineWrap.dll&#8221;</span>)[Reflection.Assembly]::LoadFile(<span style="color: #cccccc">&#8220;&#8230;\Microsoft.SQLServer.ManagedDTS.dll&#8221;</span>)</span></p>
<p>Nach diesem Schritt stehen einem alle Objekte des SSIS-Objektsmodells zur Verfügung. Der nächste Schritt ist nun sich eine SSIS-Applikationskontext zu besorgen, ein Paket zu erstellen bzw. zu öffnen, Änderungen vorzunehmen und diese wieder abzuspeichern. Hier ein Beispiel für ein Grundgerüst:</p>
<p>&nbsp;</p>
<p><span style="font-family: Courier New"><span style="color: #008040"># SSIS-Kontext erstellen</span><br />
<strong>$context</strong> = <span style="color: #9b00d3">new-object</span> Microsoft.SqlServer.Dts.Runtime.Application </span></p>
<p><span style="font-family: Courier New"><span style="color: #008040"># Neues Paket erstellen<br />
</span><strong>$package</strong> = <span style="color: #9b00d3">new-object</span> Microsoft.SqlServer.Dts.Runtime.Package </span></p>
<p><span style="font-family: Courier New"><span style="color: #008040"># Paket nach eigenen Wünschen anpassen<br />
</span><br />
<span style="color: #008040"># Aufräumen</span><br />
[System.Runtime.Interopservices.Marshal]::ReleaseComObject(<strong>$package</strong>)[System.Runtime.Interopservices.Marshal]::ReleaseComObject(<strong>$context</strong>) </span></p>
<p><span style="font-family: Courier New"><span style="color: #9b00d3">Remove-Variable</span> context<br />
<span style="color: #9b00d3">Remove-Variable</span> package</span></p>
<p>Soll ein bereits vorhandenes Paket geöffnet werden müsste das Grundgerüst entsprechend angepasst werden:</p>
<p><span style="font-family: Courier New"><strong>$context</strong>.LoadPackage<span style="color: #cccccc">(&#8220;C:\TestPackage.dtsx&#8221;</span>, <strong>$null</strong>, <strong>$false</strong>)</span></p>
<h5>Variablen erstellen und/oder anpassen</h5>
<p>Bei der Homogenisierung der Paketkonfiguration werden Variablen benötigt. Zum Beispiel können Variablen dazu verwendet werden bestimmte Connections über Expressions zu Parametrisieren. Hier ein einfaches Beispiel um dem Paket Variablen mit zu geben. Diese Variablen werden später mittels Expressions an eine Connection weitergegeben. Über diese Connection werden dann alle benötigten weiteren Connections und Variablen geladen.</p>
<p><span style="font-family: Courier New"><strong>$var</strong> = <strong>$package</strong>.Variables.Add(<span style="color: #cccccc">&#8220;AdminDBCatalog&#8221;</span>, <strong>$false</strong>, <span style="color: #cccccc">&#8220;Config&#8221;</span>, <span style="color: #cccccc">&#8220;AdminDB&#8221;</span>)<br />
<strong>$var</strong> = <strong>$package</strong>.Variables.Add(<span style="color: #cccccc">&#8220;AdminDBHostename&#8221;</span>, <strong>$false</strong>, <span style="color: #cccccc">&#8220;Config&#8221;</span>, <span style="color: #cccccc">&#8220;HOSTNAME&#8221;</span>)</span></p>
<h5>Paketkonfiguration einschalten</h5>
<p>Wie die Connections und die Variablen ist auch die Paketkonfiguration über das Objekt-Modell zu erreichen. Der Einfachheit halber verzichte ich an dieser Stelle darauf zu überprüfen ob die Konfiguration bereits existiert. Auf das grundlegende Prinzip dabei gehe ich bei der Erstellung der Connections im nächsten Abschnitt ein.</p>
<p>Im folgenden erstelle ich eine Paketkonfiguration welche einen Katalog- und Hostnamen aus einer Environmentvariable läd. Später wird eine Connection dann mit den Inhalten der Variablen parametrisiert.</p>
<p><span style="font-family: Courier New"><span style="color: #008000">#Sicherstellen, dass die Paket-Konfiguration eingeschaltet ist<br />
</span><strong>$package</strong>.EnableConfigurations = <strong>$true</strong> </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Katalog aus Envrironment-Variable laden </span></span><span style="font-family: Courier New"><br />
<strong>$config </strong>= <strong>$package</strong>.Configurations.Add()<br />
<strong>$config</strong>.Name = <span style="color: #cccccc">&#8220;AdminDBCatalog&#8221;<br />
</span></span><span style="font-family: Courier New"><strong>$config</strong>.ConfigurationType = <span style="color: #ffc000">2</span><br />
<strong>$config</strong>.ConfigurationString = </span><span style="font-family: Courier New"><span style="color: #cccccc">&#8220;AdminDBCatalog&#8221;<br />
</span><strong>$config</strong>.PackagePath = </span><span style="font-family: Courier New;color: #cccccc">&#8220;\Package.Variables[Config::AdminDBHostname].Properties[Value]&#8221; </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Katalog aus Envrironment-Variable laden<br />
</span></span><strong><span style="font-family: Courier New">$config</span></strong><span style="font-family: Courier New"> = <strong>$package</strong>.Configurations.Add()<br />
<strong>$config</strong>.Name = <span style="color: #cccccc">&#8220;AdminDBHostname&#8221;</span><br />
</span><span style="font-family: Courier New"><strong>$config</strong>.ConfigurationType = <span style="color: #ffc000">2</span><br />
$config.ConfigurationString = </span><span style="font-family: Courier New"><span style="color: #cccccc">&#8220;AdminDBHostname&#8221;<br />
</span>$config.PackagePath = </span><span style="color: #cccccc"><span style="font-family: Courier New">&#8220;\Package.Variables[Config::AdminDBCatalog].Properties[Value]&#8220;</span> </span></p>
<h5>Connections erstellen oder anpassen</h5>
<p>Wesentlicher Bestandteil einer Connection ist der Connection-String und der Connection-Type. Folgendes Beispiel zeigt die Erstellung einer einfachen OLEDB-Connection:</p>
<p><span style="font-family: Courier New"><strong>$conMgr</strong> = <strong>$package</strong>.Connections.Add(<span style="color: #cccccc">&#8220;OLEDB&#8221;</span>)<br />
<strong>$conMgr</strong>.Name = <span style="color: #cccccc">&#8220;AdminDB Connection&#8221;</span><br />
<strong>$conMgr</strong>.ConnectionString = <span style="color: #cccccc">&#8220;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AdminDB;Data Source=HOSTNAME;Auto Translate=False;&#8221;</span></span></p>
<p>Den Connection String bekommt man entweder über der Database Explorer des VS, mit dem SSIS-Designer oder von <a title="http://www.connectionstrings.com/" href="http://www.connectionstrings.com/">http://www.connectionstrings.com/</a>. Den Connection Type könnt ihr mit folgendem Befehl ermitteln:</p>
<p><span style="font-family: Courier New"><strong>$context</strong>.ConnectionInfos <span style="color: #9b00d3">|</span> <span style="color: #0000ff">select</span> ConnectionType<br />
</span><br />
<span style="font-family: Courier New">ConnectionType<br />
&#8212;&#8212;&#8212;&#8212;&#8211;<br />
ODBC<br />
FLATFILE<br />
OLEDB<br />
MULTIFILE<br />
MSOLAP100<br />
HTTP<br />
FILE<br />
ADO.NET<br />
FTP<br />
ADO<br />
MULTIFLATFILE<br />
EXCEL<br />
SQLMOBILE<br />
CACHE<br />
MSMQ<br />
SMTP<br />
WMI<br />
SMOServer</span></p>
<p>In der Regel wäre es für unser Vorhaben aber besser wenn auf das Vorhandensein der Connection geprüft und diese ggf. angepasst würde. Prüfen kann man diese wie folgt:</p>
<p><span style="font-family: Courier New"><strong>$ErrorActionPreference</strong> = <span style="color: #cccccc">&#8220;SilentlyContinue&#8221; </span><br />
<strong>$connectionName</strong> = <span style="color: #cccccc">&#8220;AdminDB Connection&#8221;</span><br />
<strong>$conMgr</strong> =<strong> $package</strong>.Connections.Item(<strong>$connectionName</strong>) </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Im Fehlerfall Connection neu anlegen</span><br />
<span style="color: #0000ff">if</span> (<strong>!$?</strong>) {<br />
<strong> $conMgr</strong> = <strong>$package</strong>.Connections.Add(<span style="color: #cccccc">&#8220;OLEDB&#8221;</span>)<br />
<strong> $conMgr</strong>.Name = <strong>$connectionName</strong><br />
}<br />
</span><span style="color: #008000"><br />
<span style="font-family: Courier New"># Connections String setzen<br />
</span></span><span style="font-family: Courier New"><strong>$conMgr</strong>.ConnectionString = <span style="color: #cccccc">&#8220;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AdminDB;Data Source=<span style="color: #ff0000">ANDERESOURCE</span>;Auto Translate=False;&#8221;</span></span></p>
<p><span style="font-family: Courier New"><span style="font-family: Verdana">Diese Technik stellt sicher, dass die Connection angelegt wird oder wenn bereits vorhanden, angepasst wird. Im zweiten Schritt wird die Connection so mit Expressions parametrisiert, dass die Connection dynamisch von den beiden Enronmentvariablen AdminDBCatalog und AdminDBHost abhängt.</span> </span></p>
<p><span style="font-family: Courier New"><span style="color: #008000"># Connection an die Paketkonfiguration koppeln</span><br />
<strong>$conMgr</strong>.SetExpression(<span style="color: #cccccc">&#8220;InitialCatalog&#8221;</span>, <span style="color: #cccccc">&#8220;@[Config::AdminDBCatalog]&#8220;</span>)<br />
<strong>$conMgr</strong>.SetExpression(<span style="color: #cccccc">&#8220;ServerName&#8221;</span>, <span style="color: #cccccc">&#8220;@[Config::AdminDBHostname]&#8220;</span>)</span></p>
<h5>Speichern des Pakets</h5>
<p>Gespeichert werden kann das Paket mit folgendem Kommando:</p>
<p><span style="font-family: Courier New"><strong>$context</strong>.SaveToXml(<span style="color: #cccccc">&#8220;C:\TestPaket.dtsx&#8221;</span>, <strong>$null</strong>)</span></p>
<h5>Fazit und Ausblick</h5>
<p>Im weiteren Verlauf wäre es wohl Ratsam weitere Fehler abzufangen. Des weiteren müssten weitere Variablen und Connections hinzugefügt werden, die man über eine Konfigurationsdatenbank konfigurieren will. Zum Schluss müsste noch die Paketkonfiguration angepasst werden, so dass weitere Inhalte aus der Konfigurationsdatenbank in Variablen geladen werden.</p>
<p>Wie jedoch zu sehen ist kann man mit PoweShell-Skripten und relativ wenigen Zeilen einen kleinen IS-Paket-Generator schreiben der auch noch leicht zu verstehen und zu erweitern ist.</p>
<p>Die Arbeit für solch ein Skript hat man genau einmal. Sich bei jeder Änderung der Konfiguration oder der Implementierung neuer Pakete durch die Dialoge der Paketkonfiguration zu klicken ist recht mühsam, Fehleranfällig und zeitverschwenderisch.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.oraylis.de/2012/03/templating-mechanismus-fr-integration-service-pakete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSIS Goodie #1: Excel + SSIS + 64 bit = DTS_E_OLEDB_EXCEL_NOT_SUPPORTED ?</title>
		<link>http://blog.oraylis.de/2011/05/ssis-goodie-1-excel-ssis-64-bit-dts_e_oledb_excel_not_supported/</link>
		<comments>http://blog.oraylis.de/2011/05/ssis-goodie-1-excel-ssis-64-bit-dts_e_oledb_excel_not_supported/#comments</comments>
		<pubDate>Mon, 02 May 2011 16:06:50 +0000</pubDate>
		<dc:creator>Daniel Esser</dc:creator>
				<category><![CDATA[MS SSIS]]></category>
		<category><![CDATA[64Bit]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[OLEDB]]></category>

		<guid isPermaLink="false">http://blog.oraylis.de/?p=1024</guid>
		<description><![CDATA[<p style="text-align: justify">The current majority opinion is that the current Office OLEDB provider (Microsoft.ACE.OLEDB.12.0) and 64-Bit environment can&#8217;t work together. In fact there are some problems using the provider in a 64Bit environment. If you want to know how to use it in SSIS the right way read this article.</p>
<p><span id="more-1024"></span>Some facts about the Office OLEDB provider and SSIS:</p>
<p><strong>Currently the Office OLEDB provider is 32 bit only!</strong></p>
<p style="text-align: justify">That is wrong! Microsoft provides a 64 bit version since December 2010. You can download it here: <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c06b8369-60dd-4b64-a44b-84b371ede16d&amp;displaylang=en">Microsoft Access Database Engine 2010 Redistributable</a></p>
<p><strong>Developing SSIS packages with the 64 bit Version of the provider does not work!</strong></p>
<p style="text-align: justify">Unfortunately Microsoft provides Visual Studio as 32 bit application only (<a href="http://blogs.msdn.com/b/ricom/archive/2009/06/10/visual-studio-why-is-there-no-64-bit-version.aspx">Why?</a>). Therefore it can&#8217;t access/use 64 bit OLEDB providers. As a consequence of that fact you cannot select the Office OLEDB provider. In an development environment you have to use the 32 bit provider.</p>
<p><strong>Excuting SSIS packages in an 64 bit environment with 64 bit OLE DB driver does not work!</strong></p>
<p style="text-align: justify">Yes and no! Using the original Excel-Source does not work. It seems that Microsoft implemented an hard if-statement which throws an exception (DTS_E_OLEDB_EXCEL_NOT_SUPPORTED:  The Excel Connection  Manager is not supported in the 64-bit version of  SSIS, as no OLE DB  provider is available.) if these conditions are met:</p>
<ul>
<li>DTS-Engine runs in 64 bit environment</li>
<li>Connection string is &#8220;Microsoft.ACE.OLEDB.12.0&#8243;</li>
</ul>
<p style="text-align: justify">One solution for that is to use the standard OLEDB Source. Select Microsoft.ACE.OLEDB.12.0 as OLEDB provider and set the <em>extended properties</em> to &#8220;Excel 14.0;HDR=YES&#8221;. Now you can use the normal OLEDB source to retrieve data from an Excel file. I found no restrictions so far.</p>
<p><strong>Excel has to be installed where the SSIS package is to be executed!</strong></p>
<p style="text-align: justify">That is wrong. You only need the <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c06b8369-60dd-4b64-a44b-84b371ede16d&amp;displaylang=en">Microsoft Access Database Engine 2010 Redistributable</a></p>
<p>The lesson is clear: Using Office OLEDB in a 64 bit environment with SSIS works (At least at the command line with DTEXEC)!</p>
<p><a href="http://www.twitter.com/LinkTechie"><img src="http://twitter-badges.s3.amazonaws.com/follow_me-b.png" alt="Follow LinkTechie on Twitter" /></a></p>
<div style="display:block"><small><em>by Daniel Esser <ul class="addtoany_list"><li><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.oraylis.de%2F2011%2F05%2Fssis-goodie-1-excel-ssis-64-bit-dts_e_oledb_excel_not_supported%2F&amp;linkname=SSIS%20Goodie%20%231%3A%20Excel%20%2B%20SSIS%20%2B%2064%20bit%20%3D%20DTS_E_OLEDB_EXCEL_NOT_SUPPORTED%20%3F"><img src="http://blog.oraylis.de/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a></li></ul></em></small></div>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">The current majority opinion is that the current Office OLEDB provider (Microsoft.ACE.OLEDB.12.0) and 64-Bit environment can&#8217;t work together. In fact there are some problems using the provider in a 64Bit environment. If you want to know how to use it in SSIS the right way read this article.</p>
<p><span id="more-1024"></span>Some facts about the Office OLEDB provider and SSIS:</p>
<p><strong>Currently the Office OLEDB provider is 32 bit only!</strong></p>
<p style="text-align: justify">That is wrong! Microsoft provides a 64 bit version since December 2010. You can download it here: <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c06b8369-60dd-4b64-a44b-84b371ede16d&amp;displaylang=en">Microsoft Access Database Engine 2010 Redistributable</a></p>
<p><strong>Developing SSIS packages with the 64 bit Version of the provider does not work!</strong></p>
<p style="text-align: justify">Unfortunately Microsoft provides Visual Studio as 32 bit application only (<a href="http://blogs.msdn.com/b/ricom/archive/2009/06/10/visual-studio-why-is-there-no-64-bit-version.aspx">Why?</a>). Therefore it can&#8217;t access/use 64 bit OLEDB providers. As a consequence of that fact you cannot select the Office OLEDB provider. In an development environment you have to use the 32 bit provider.</p>
<p><strong>Excuting SSIS packages in an 64 bit environment with 64 bit OLE DB driver does not work!</strong></p>
<p style="text-align: justify">Yes and no! Using the original Excel-Source does not work. It seems that Microsoft implemented an hard if-statement which throws an exception (DTS_E_OLEDB_EXCEL_NOT_SUPPORTED:  The Excel Connection  Manager is not supported in the 64-bit version of  SSIS, as no OLE DB  provider is available.) if these conditions are met:</p>
<ul>
<li>DTS-Engine runs in 64 bit environment</li>
<li>Connection string is &#8220;Microsoft.ACE.OLEDB.12.0&#8243;</li>
</ul>
<p style="text-align: justify">One solution for that is to use the standard OLEDB Source. Select Microsoft.ACE.OLEDB.12.0 as OLEDB provider and set the <em>extended properties</em> to &#8220;Excel 14.0;HDR=YES&#8221;. Now you can use the normal OLEDB source to retrieve data from an Excel file. I found no restrictions so far.</p>
<p><strong>Excel has to be installed where the SSIS package is to be executed!</strong></p>
<p style="text-align: justify">That is wrong. You only need the <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c06b8369-60dd-4b64-a44b-84b371ede16d&amp;displaylang=en">Microsoft Access Database Engine 2010 Redistributable</a></p>
<p>The lesson is clear: Using Office OLEDB in a 64 bit environment with SSIS works (At least at the command line with DTEXEC)!</p>
<p><a href="http://www.twitter.com/LinkTechie"><img src="http://twitter-badges.s3.amazonaws.com/follow_me-b.png" alt="Follow LinkTechie on Twitter" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.oraylis.de/2011/05/ssis-goodie-1-excel-ssis-64-bit-dts_e_oledb_excel_not_supported/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>BIDS Goodie #1: How to use macros with SSIS</title>
		<link>http://blog.oraylis.de/2011/02/bids-goodie-1-how-to-use-macros-with-ssis/</link>
		<comments>http://blog.oraylis.de/2011/02/bids-goodie-1-how-to-use-macros-with-ssis/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 13:41:06 +0000</pubDate>
		<dc:creator>Daniel Esser</dc:creator>
				<category><![CDATA[MS SSIS]]></category>
		<category><![CDATA[BIDS]]></category>
		<category><![CDATA[Goodie]]></category>
		<category><![CDATA[Macro]]></category>

		<guid isPermaLink="false">http://blog.oraylis.de/?p=973</guid>
		<description><![CDATA[<p>Do you ever used macros in Visual Studio? You can do also in BIDS and SSIS&#8230;</p>
<p><span id="more-973"></span>There are many recurring tasks via ETL development. I will now explain how to write a macro to automate these recurring tasks. For example we want to add a frequently used connection manager. Unfortunately the Visual Studio Macros environment isn&#8217;t set up correctly for this.</p>
<p>Go to the Microsoft SQL Server SDK folder: C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies</p>
<p>Copy the following assemblies: Microsoft.SqlServer.DTSPipelineWrap.dll Microsoft.SQLServer.DTSRuntimeWrap.dll</p>
<p>To the Visual Studio Public Assemblies folder: C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies</p>
<p>Now start <em>Visual Studio</em> and open an SSIS project. Select <strong>Other Windows</strong> and then <strong>Macro Explorer</strong> (<em>Alt+F8</em>). Right click on <strong>Macros </strong>in the <strong>Macro Explorer</strong> and select <strong>New Macro Project </strong>called <strong>MySSISMacros</strong>. Create a new module called <strong>Samples</strong>. Double click <strong>Samples </strong>to open the <em>Macro Editor</em>.</p>
<p style="padding-left: 30px;text-align: center"><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/MacroExplorer.png"><img class="aligncenter size-full wp-image-980" style="border: 1px solid black" src="http://blog.oraylis.de/wp-content/uploads/2011/02/MacroExplorer.png" alt="" width="295" height="141" /></a></p>
<p style="padding-left: 30px;text-align: left">In the <em>Macro Editor</em> right click at the <strong>MySSISMacros</strong> project and select <strong>Add reference</strong>. Add references to the assemblies above and click <strong>OK</strong>.</p>
<p style="padding-left: 30px;text-align: left"><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/AddReferenceMacroExplorer.png"><img class="aligncenter size-full wp-image-986" src="http://blog.oraylis.de/wp-content/uploads/2011/02/AddReferenceMacroExplorer.png" alt="" width="580" height="266" /></a></p>
<p style="text-align: left">Now you are ready to write macros for SSIS development. Here is a very simple example:<span style="color: #3366ff"> </span></p>
<pre style="text-align: left;padding-left: 30px"><span style="color: #3366ff">Imports </span>System
<span style="color: #3366ff">Imports </span>EnvDTE
<span style="color: #3366ff">Imports </span>EnvDTE80
<span style="color: #3366ff">Imports </span>EnvDTE90
<span style="color: #3366ff">Imports </span>EnvDTE90a
<span style="color: #3366ff">Imports </span>System.Diagnostics
<span style="color: #3366ff">Imports </span>Microsoft.SqlServer.Dts.Runtime</pre>
<pre style="text-align: left;padding-left: 30px"><span style="color: #3366ff">Public </span>Module Samples

<span style="color: #3366ff">    Public Sub</span> Example01()
        <span style="color: #3366ff">Dim </span>app <span style="color: #3366ff">As </span><span style="color: #3366ff">New </span>Microsoft.SqlServer.Dts.Runtime.Application()
        <span style="color: #3366ff">Dim </span>filename <span style="color: #3366ff">As </span>String

        filename = DTE.ActiveDocument.FullName()
        <span style="color: #3366ff">Dim </span>p As Package

        <span style="color: #339966">'' Save the document before making changes</span>
        DTE.ActiveDocument.Save()

        <span style="color: #339966">'' Open the package</span>
        p = app.LoadPackage(filename, <span style="color: #3366ff">Nothing</span>)

        <span style="color: #339966">'' Do some changes</span>
        <span style="color: #0000ff">Dim </span>cm As ConnectionManager
        <span style="color: #0000ff">Dim </span>connString, dataSource, catalog, provider, appName <span style="color: #0000ff">As </span>String

        dataSource = <span style="color: #993300">"."</span>
        catalog = <span style="color: #993300">"AdventureWorksDW2008"</span>
        provider = <span style="color: #993300">"SQLNCLI10.1"</span>
        appName = p.Name
        connString = String.Format(<span style="color: #993300">"Data Source={0};Initial Catalog={1};Provider={2};
             Integrated Security=SSPI;Application Name={3};Auto Translate=False;"</span>
             , dataSource, catalog, provider, appName)

        cm = p.Connections.Add(<span style="color: #993300">"OLEDB"</span>)
        cm.ConnectionString = connString
        cm.Description = "AdventureWorks DW"
        cm.Name = "AdventureWorksDW"

        <span style="color: #339966">'' Save the package</span>
        app.SaveToXml(filename, p, <span style="color: #3366ff">Nothing</span>)
<span style="color: #3366ff">    End Sub
End Module

</span></pre>
<p>Download: <span style="color: #3366ff"> </span><span style="color: #3366ff"><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/Samples.zip">Samples.zip</a></span></p>
<p><span style="color: #3366ff"> </span></p>
<p>Now open a package and execute the macro. It will add a connection to the active package.</p>
<p style="text-align: left">
<div style="width: 1px;height: 1px;overflow: hidden">Public Module Samples</p>
<p>Public Sub Example01()<br />
Dim a As New Microsoft.SqlServer.Dts.Runtime.Application()<br />
Dim filename As String</p>
<p>filename = DTE.ActiveDocument.FullName()<br />
Dim p As Package</p>
<p>&#8221; Save the document before making changes<br />
DTE.ActiveDocument.Save()</p>
<p>&#8221; Open the package<br />
p = a.LoadPackage(filename, Nothing)</p>
<p>&#8221; Do some changes<br />
p.CreatorName = &#8220;test&#8221;</p>
<p>&#8221; Save the package<br />
a.SaveToXml(filename, p, Nothing)</p>
<p>End Sub<br />
End Module</p>
</div>
<div style="display:block"><small><em>by Daniel Esser <ul class="addtoany_list"><li><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fblog.oraylis.de%2F2011%2F02%2Fbids-goodie-1-how-to-use-macros-with-ssis%2F&amp;linkname=BIDS%20Goodie%20%231%3A%20How%20to%20use%20macros%20with%20SSIS"><img src="http://blog.oraylis.de/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a></li></ul></em></small></div>]]></description>
			<content:encoded><![CDATA[<p>Do you ever used macros in Visual Studio? You can do also in BIDS and SSIS&#8230;</p>
<p><span id="more-973"></span>There are many recurring tasks via ETL development. I will now explain how to write a macro to automate these recurring tasks. For example we want to add a frequently used connection manager. Unfortunately the Visual Studio Macros environment isn&#8217;t set up correctly for this.</p>
<p>Go to the Microsoft SQL Server SDK folder: C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies</p>
<p>Copy the following assemblies: Microsoft.SqlServer.DTSPipelineWrap.dll Microsoft.SQLServer.DTSRuntimeWrap.dll</p>
<p>To the Visual Studio Public Assemblies folder: C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies</p>
<p>Now start <em>Visual Studio</em> and open an SSIS project. Select <strong>Other Windows</strong> and then <strong>Macro Explorer</strong> (<em>Alt+F8</em>). Right click on <strong>Macros </strong>in the <strong>Macro Explorer</strong> and select <strong>New Macro Project </strong>called <strong>MySSISMacros</strong>. Create a new module called <strong>Samples</strong>. Double click <strong>Samples </strong>to open the <em>Macro Editor</em>.</p>
<p style="padding-left: 30px;text-align: center"><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/MacroExplorer.png"><img class="aligncenter size-full wp-image-980" style="border: 1px solid black" src="http://blog.oraylis.de/wp-content/uploads/2011/02/MacroExplorer.png" alt="" width="295" height="141" /></a></p>
<p style="padding-left: 30px;text-align: left">In the <em>Macro Editor</em> right click at the <strong>MySSISMacros</strong> project and select <strong>Add reference</strong>. Add references to the assemblies above and click <strong>OK</strong>.</p>
<p style="padding-left: 30px;text-align: left"><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/AddReferenceMacroExplorer.png"><img class="aligncenter size-full wp-image-986" src="http://blog.oraylis.de/wp-content/uploads/2011/02/AddReferenceMacroExplorer.png" alt="" width="580" height="266" /></a></p>
<p style="text-align: left">Now you are ready to write macros for SSIS development. Here is a very simple example:<span style="color: #3366ff"> </span></p>
<pre style="text-align: left;padding-left: 30px"><span style="color: #3366ff">Imports </span>System
<span style="color: #3366ff">Imports </span>EnvDTE
<span style="color: #3366ff">Imports </span>EnvDTE80
<span style="color: #3366ff">Imports </span>EnvDTE90
<span style="color: #3366ff">Imports </span>EnvDTE90a
<span style="color: #3366ff">Imports </span>System.Diagnostics
<span style="color: #3366ff">Imports </span>Microsoft.SqlServer.Dts.Runtime</pre>
<pre style="text-align: left;padding-left: 30px"><span style="color: #3366ff">Public </span>Module Samples

<span style="color: #3366ff">    Public Sub</span> Example01()
        <span style="color: #3366ff">Dim </span>app <span style="color: #3366ff">As </span><span style="color: #3366ff">New </span>Microsoft.SqlServer.Dts.Runtime.Application()
        <span style="color: #3366ff">Dim </span>filename <span style="color: #3366ff">As </span>String

        filename = DTE.ActiveDocument.FullName()
        <span style="color: #3366ff">Dim </span>p As Package

        <span style="color: #339966">'' Save the document before making changes</span>
        DTE.ActiveDocument.Save()

        <span style="color: #339966">'' Open the package</span>
        p = app.LoadPackage(filename, <span style="color: #3366ff">Nothing</span>)

        <span style="color: #339966">'' Do some changes</span>
        <span style="color: #0000ff">Dim </span>cm As ConnectionManager
        <span style="color: #0000ff">Dim </span>connString, dataSource, catalog, provider, appName <span style="color: #0000ff">As </span>String

        dataSource = <span style="color: #993300">"."</span>
        catalog = <span style="color: #993300">"AdventureWorksDW2008"</span>
        provider = <span style="color: #993300">"SQLNCLI10.1"</span>
        appName = p.Name
        connString = String.Format(<span style="color: #993300">"Data Source={0};Initial Catalog={1};Provider={2};
             Integrated Security=SSPI;Application Name={3};Auto Translate=False;"</span>
             , dataSource, catalog, provider, appName)

        cm = p.Connections.Add(<span style="color: #993300">"OLEDB"</span>)
        cm.ConnectionString = connString
        cm.Description = "AdventureWorks DW"
        cm.Name = "AdventureWorksDW"

        <span style="color: #339966">'' Save the package</span>
        app.SaveToXml(filename, p, <span style="color: #3366ff">Nothing</span>)
<span style="color: #3366ff">    End Sub
End Module

</span></pre>
<p>Download: <span style="color: #3366ff"> </span><span style="color: #3366ff"><a href="http://blog.oraylis.de/wp-content/uploads/2011/02/Samples.zip">Samples.zip</a></span></p>
<p><span style="color: #3366ff"> </span></p>
<p>Now open a package and execute the macro. It will add a connection to the active package.</p>
<p style="text-align: left">
<div style="width: 1px;height: 1px;overflow: hidden">Public Module Samples</p>
<p>Public Sub Example01()<br />
Dim a As New Microsoft.SqlServer.Dts.Runtime.Application()<br />
Dim filename As String</p>
<p>filename = DTE.ActiveDocument.FullName()<br />
Dim p As Package</p>
<p>&#8221; Save the document before making changes<br />
DTE.ActiveDocument.Save()</p>
<p>&#8221; Open the package<br />
p = a.LoadPackage(filename, Nothing)</p>
<p>&#8221; Do some changes<br />
p.CreatorName = &#8220;test&#8221;</p>
<p>&#8221; Save the package<br />
a.SaveToXml(filename, p, Nothing)</p>
<p>End Sub<br />
End Module</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.oraylis.de/2011/02/bids-goodie-1-how-to-use-macros-with-ssis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

