A Better Starting Point for .Net Console Applications

Often when prototyping .Net applications, I end up starting with a console app (as things get more complicated or require interactivity, I move to Windows forms).  It takes about 1 minute to get up and running with a console app. . . unless you want to start passing fancy parameters and things like that.  It doesn’t take much more effort, but the point is that you don’t want to re-invent the console app code, you want to spend your time prototyping.

Sometimes your production application might require a console app.  In my case, one portion of the application I am working on will need to be implemented as a console app (for now) so that it can be executed from a SQL Server Agent job.  I want the console app to be robust and production-ready, very different from the prototype apps I cobble together in the span of a couple of minutes.

image

In support of a more robust console application, I found a blog post with a great template put together by Alois Kraus.  There is a blog post covering the basics, and the template can be downloaded from the Visual Studio Gallery.

At a high level, the custom console template starts you off in a Cadillac instead of a bicycle when building a console application.  Right out of the gate you get a nice command line parser, help output, color console and much more robust error handling.  I doubt I will start with the basic console template again.

Using an Entity Framework Data Model in Multiple Projects

I’m starting to dig into Entity Framework 4 as part of a project that I am working on.  It is great, much easier than the old school data access methods in terms of getting up and running (it takes about 3 minutes).  There are a lot of articles out there, but I have still had to figure out a few less-obvious things along the way.

As part of getting my app ready for production, I am moving the data access layer to its own project.  I started out by creating a new project in my solution and then within that project I created a new entity data model.  After that, I just added the entity model project as a reference on my sample app project.  I was missing some references, so figured out I needed to add the following using statements:

using System.Data.Objects;
using System.Data.Objects.DataClasses;

After this I was a lot closer, able to compile the app but no data was being returned.  After a bit of searching, this article helped me a ton.  The only other thing I was missing was the connection string, which I didn’t even know existed partly due to the fact that Entity Framework is so easy to get up and running via the wizard, which hides this from you.  After I copied the connection string directly from Entity Model project, I just pasted it into the <configuration> section of the App.Config of my sample app and it worked perfectly right away.

  <connectionStrings>
    <add name="MyEntities" connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(local);initial catalog=MyDB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

Editing Existing SSIS Package via EzAPI or Standard SSIS API Doesn’t Update Layout in BIDS

As part of a project I am working on that requires me to programmatically alter existing packages, I ran into an annoyance (bug?) in SSIS that makes it hard to open packages after altering them.

The Problem

During an exchange on Codeplex forums with Matt Masson from the SSIS team, he summarized the workflow as follows:

  1. Created the package in Visual Studio
  2. Added stuff to it
  3. Saved it out to disk
  4. Opened and modified it with EzAPI

When I follow this workflow to add 10 connection managers, sequencimagee containers and execute package tasks programmatically to an existing package with nothing in the design surface, you will end up with a package that will show connection managers, but no sequence containers or execute package tasks.

As you can see in the screenshot to the right, there are a lot of connection managers visible, but no accompanying sequence container or execute package task.

If you looimagek at the Package Explorer tab, you will see that all of the “missing” sequence containers and execute package tasks were actually created and do exist in the package. You can see this in the Package Explorer in the screenshot to the left.  Additionally, if you execute the package from BIDS, programmatically added components appear in the output, just no green boxes or row counts in the Control Flow or Data Flow.

 

 

 

The Solution

Based on Matt Masson’s response to my question posted in the discussion area for EzAPI on Codeplex, I started digging into the XML layout code that is included at the end of the .dtsx package.  I found a blog post from the SQL Server Forum Support team that actually identified the problem I described above, and a solution.  Essentially the problem is that when a package is created in BIDS, the layout is created and stored inside a tag called <DTS:PackageVariable>.  When you modify a package programatically, this code is not updated since it is “BIDS generated code”.  When you open a package in BIDS after it has been altered, BIDS sees the existing layout code and doesn’t bother to parse the rest of the package to check for any missing objects for which layout code has not yet been created.

This problem does not occur on packages that are created programmatically from scratch because BIDS is able to detect that no layout code exists and will generate all of it the first time the package is opened and perform an auto-layout.

I adapted the code found at the SQL Server Forum Support Team FAQ to EzAPI with no additional problems.  One thing that I found is that there can be multiple <DTS:PackageVariable> sections, and IDS will not generate layout code until all of them have been removed.  To that end, my code uses Regex to get a count of how many code blocks will need to be purged.  Here is a sample of my adapted code (original is at the blog post linked above):

//Save the package object to XML
string strXML = null;
strXML = TestPackage.SaveToXML();

//Count instances of existing SSIS layout code in package.
int LayoutCount = Regex.Matches(strXML, "<DTS:PackageVariable>").Count;

//Remove the layout information.
for (int i = 0; i < LayoutCount; i++)
{
    strXML = strXML.Remove(strXML.IndexOf("<DTS:PackageVariable>"), strXML.IndexOf("</DTS:PackageVariable>") - strXML.IndexOf("<DTS:PackageVariable>") + 22);
}

Based on comments that Matt made, I am hopeful that this has been fixed in SQL 2012, but the problem does exist in 2005, 2008 and 2008 R2.  If I discover any further useful information, I will update this blog post, but at a high level I think that I have covered the problem and solution.

Developing Microsoft SSIS packages programmatically with EZAPI

I recently started working on a task that required me to dig into creating SQL Server Integration Services packages programmatically.  There is not a lot of info out there on this, so thought it might be beneficial for me to blog a bit as I go in case other benefit from this.

Relatively early on in my investigation I found that the internal SSIS test team at Microsoft has created and released a second level API for SSIS called EzAPI that sits on top of the native SSIS API.  Using EzAPI, you can create packages and package objects in only a couple lines of simple code, vs. trying to decipher the somewhat esoteric COM wrapper APIs for SSIS.

You can read about EzAPI on the SSIS Team Blog here.

An update was released in late 2010, which you can read about here.  This update added a lot of additional components to the API.

You can download it here (including source code and samples).

The objects that are supported are as follows:

Tasks and Containers
  • For Loop container
  • DataFlow Task
  • Execute Package Task
  • ActiveX Script Task
DataFlow Components
  • OLEDB Source
  • OLEDB Destination
  • FlatFile Source
  • FlatFile Destination
  • ADO.Net Source
  • ADO.Net Destination
  • Multicast Transform
  • Derived Column Transform
  • Sort Transform
  • OLEDB command Transform
  • Lookup Transform
  • Cache Transform
  • Data Convert Transform
  • Aggregate Transform
Connection Managers
  • OLEDB Connection manager (including specific versions for SQL Server, Oracle, DB2)
  • FILE connection manager
  • FLATFILE connection manager
  • CACHE connection manager
  • ADO.NET connection manager

ADDED IN DECEMBER 2010 UPDATE

  • Sequence container
  • For each loop container
  • Transfer database task
  • Execute process task
  • File system task
  • Execute SQL task
  • Excel source adapter
  • Excel destination adapter
  • Union all transform
  • Merge & Merge join transform
  • Conditional split transform
  • SCD transform

SQL 2012 RC0

Microsoft has release SQL Server 2012 RC0.
http://www.microsoft.com/download/en/details.aspx?id=28145

You can also get the RC0 release of PowerPivot for Excel 2010.
http://www.microsoft.com/download/en/details.aspx?id=28150

Table Size History

When maintaining a data warehouse, it is import understand the size and disk requirements of your tables over time. My current client has asked that I generate a report showing table disk usage over time, so that we can predict table growth.

I was looking around and found the procedure sp_spaceused. This returns the row count, data usage and index usage for a given table. I decided to create a fact table to save the table info on a daily basis. The SSIS package should not be too difficult to create but it turned out to be a much bigger challenge then I expected.

First I created a Fact Table and couple of Dimension Tables. I took my standard Dim.Date and Created a Dim.TableDefinition to store the table name and other table related info. I used sys.tables to get the base info.

CREATE TABLE Fact.TableSize(
	TableSizeKey int IDENTITY(1,1) NOT NULL,
	RunDateKey int NULL,
	LastInsertDateKey int NULL,
	TableDefinitionKey int NULL,
	TableRows bigint NULL,
	ReservedSpace bigint NULL,
	DataSpace bigint NULL,
	IndexSpace bigint NULL)

CREATE TABLE Dim.TableDefinition(
	TableDefinitionKey int IDENTITY(1,1) NOT NULL,
	SchemaName varchar(50) NOT NULL,
	TableName varchar(50) NOT NULL,
	TableSchemaName varchar(100) NOT NULL,
	TableDescription varchar(max) NULL)

--Populate Dim.TableDefinition
SELECT
	S.name + '.' + T.name  AS TableSchemaName
	,S.name AS SchemaName
	,T.name  AS TableName
	,NULL AS TableDescription
FROM sys.tables T
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
WHERE LEFT(T.name, 3) IN ('dim','fac')

To create the SSIS package I started off in the Data flow. I first created an OLE DB Source, with the SQL command

 sp_spaceused 'dbo.Table1' 

and clicked on the Columns tab. I was sad to see that the Editor only pulled back the default set of columns that the procedure returns, when no parameters are passed in.

To get the proper output I stubbed out a select statement before calling the procedure.

IF 1 = 2 BEGIN
	DECLARE @SchemaStub TABLE
		(TableName VARCHAR(50)
		,TableRows VARCHAR(50)
		,ReservedSpace VARCHAR(50)
		,DataSpace VARCHAR(50)
		,IndexSpace VARCHAR(50)
		,UnusedSpace VARCHAR(50))

	SELECT  TableName
		,TableRows
		,ReservedSpace
		,DataSpace
		,IndexSpace
		,UnusedSpace
	FROM @SchemaStub
END

EXEC sp_spaceused 'dbo.DimDate'

The next problem I encountered is when I tried to pull the table name from a variable.

IF 1 = 2
	…
END
EXEC sp_spaceused  @objname  = ?
 

Error: Parameters cannot be extracted from the SQL command….

I also tried declaring @objname at the top, but that did not work either. So I decided to change the select statement into a variable.

Back on the Control Flow I created an Execute SQL Task. I used a SELECT against sys.tables to get a list of all fact and dimension tables. The Result Set of the task is saved to an Object variable, vTableList. I then used a For Each Loop, for each table value in the vTableList. I then used a Script Task to replace the table name in the select statement above.


        Dts.Variables("vSpaceUsedSQL").Value = "IF 1 = 2 BEGIN DECLARE @SchemaStub TABLE( " & _
            "TableName VARCHAR(50),TableRows VARCHAR(20),ReservedSpace VARCHAR(20),DataSpace VARCHAR(20),IndexSpace VARCHAR(20))" & _
            " Select TableName,TableRows,ReservedSpace,DataSpace,IndexSpace " & _
            " FROM    @SchemaStub END" & _
            " EXEC sp_spaceused '" & Dts.Variables("vTableName").Value & "'"
 

To wrap up the package
1. I added a SQL Task to delete any data from today, incase it is run twice in the same day.
2. Set the RunDateKey to the key value of GETDATE()
3. I created some pretty Reporting service reports to show my table sizes over time.

Strange SSIS Error for Configurations on Configuration Table Data Type Change from NVARCHAR to VARCHAR

Recently I got a strange SSIS error.  The error was for each of the package configurations I had in place that pulled their values from the SSIS Config table.  The ones that used the .dtsConfig file or environment variables were not throwing errors.  Here is the exact error:

Warning: The package path referenced an object that cannot be found: "停捡慫敧嘮牡慩汢獥䍛湯楦㩧挺普卓卉牅潲䵲楡卬扵敪瑣⹝牐灯牥楴獥噛污敵]". This occurs when an attempt is made to resolve a package path to an object that cannot be found.

and a screenshot of what it looked like (note foreign-language error message?):

image

 

The problem was that I had changed the various fields in the SSIS Configuration table (the one that is autogenerated by SSIS when you create your first Configuration) from NVARCHAR(255) to VARCHAR(255) to be consistent with the rest of my database.  For some reason, SSIS expects NVARCHAR, but doesn’t warn you that this is the actual problem.  Changing the data types back fixed the problem immeidately.

Atlanta SQL Saturday #89 – Check out the BRAIN POWER!!!…

Tim Radney (Blog|Twitter:@TRadney), our wonderful and most excellent leader in organizing our SQL Saturday #89 up here in Atlanta, GA, blogged recently about the difficulties involved in organizing such an event.  That blog post can be found here.  What stands out for me and what I feel is important to note is the number of Microsoft MVPs and even Microsoft employees scheduled to speak.  Currently, there are 14 MVPs and 3 MS employees.  And two of them are hosting PreCons!!!  Here’s the awesome list:

I don’t know about other SQL Saturdays, but that is a lot of brain power here.  So be sure to see and meet these fine folks, this coming September!  Be there, or be square!

My two and a half cents!!!…

SSIS Logging and Auditing Framework

Thank you for all of you that came out to my presentation at the Atlanta Microsoft BI user group, last Monday. We had a pretty good turn out, 40+.

The slide deck can be found on the user group web site. http://atlantabi.sqlpass.org/Resources.aspx

Here are the links to the other posts that I referred to during the presentation.

  • Customize SSIS Logging – Avoid dups in Parent Packages
  • Table Auditing with XML
  • An alternate, perhaps better view of the SQL Saturday #89′s AWESOME schedule!!!…

    I’ve seen on Twitter and heard over the grapevine that the SQL Saturday website can be managed a lot better.  Now while that is true, for an extension of PASS, it’s a common look and feel web tool for user groups to host a SQL Saturday event in their backyard.

    But here we are now posting the schedule for SQL Saturday #89 to be held in Atlanta, GA on September 17!  Want to see a better view.  Check out the image below, linked to a bigger image.

    Better yet, want to check it out in MS Excel?  Well here you go!

    So check it out, and make plans to attend!!!

    Thanks, and again, just my Two and a Half Cents!!!…