Code Reference A collection of code for my reference (and perhaps other people too)

2Apr/100

Using external libraries in a SSIS Script Component

I found myself needing to encrypt a column of data in a SSIS package.
I added a Script Component that would take one field from the database and return the same field encrypted.
The library that does the encrypting was not written in Visual Studio. It was created in Power Basic I think.

Normally, you would just import the library using DLLImport and run the method you need. Like this:

private const string MYENCRYPTOR = @"C:\Encrypt.dll";

[DllImport(MYENCRYPTOR, EntryPoint = "ENCRYPTMYID", SetLastError = true, CharSet = CharSet.Ansi)]
private static extern string EncryptMyId(int myId);
...
...
...
string encryptedId = EncryptMyId(id);

This works in a normal project, but for some reason I do not know, it will not work in an SSIS package.
To fix this, I created a Console Application wrapper for the encrypt method.
The console application accepts the ID as an input variable and returns the encrypted ID as a string.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ExcryptThis
{
    class Program
    {
        private const string MYENCRYPTOR = @"C:\Encrypt.dll";

        [DllImport(MYENCRYPTOR, EntryPoint = "ENCRYPTMYID", SetLastError = true, CharSet = CharSet.Ansi)]
        private static extern string EncryptMyId(int myId);

        static void Main(string[] args)
        {
            string sId;
            if (args.Count<string>() > 0)
            {
                sId = args[0];

                try
                {
                    int id = Convert.ToInt32(sId);
                    string encryptedId = EncryptMyId(id);
                    Console.Write(encryptedId);
                }
                catch (Exception ex) { }
            }
        }
    }
}

Note: be sure to use a Console.Write and not a .WriteLine or you will add a "\r\n" at the end of the returned value.

Then, in the SSIC Script Component, I call the console application as I described in my previous post.

Wrapped in the console application it runs fine.

24Mar/100

Debugging SSIS Script Component

MS chose not to allow breakpoints in the script of the Script Component. Now, debugging must be done by other more primitive methods. Here are a list of tips to help you out:

  • MessageBox.Show(): Luckily, the MessageBox works. Add some Message Boxes to your code to see what happens.
  • Data Viewer: In the Data Flow Path Editor (double click the green arrow connecting your boxes in the Data Flow) allows you to adda Data View. If you add one before and after your Script Component, you can see what data went into the script editor, and what came out.

    Double click the arrow before your Script Component and Select Data Viewers from the list. Click 'Add' then choose Grid. Click the 'Grid' tab to select the columns you want in the grid.

    When you run the package, it will pop up a grid and wait for you to continue the flow.

  • Fire methods: The fire methods (FireProgress, FireInformation, FireError, etc) allow you to output information to the Output window during run time and to the Progress tab during run time. Only FireProgress outputs to the Progress tab. The others output to the Output window.

    Below is an example:

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        bool c = true;
        // Output to the Progress tab
        ComponentMetaData.FireProgress("Input0_ProcessInputRow()", 0, 0, 1, "Row: " + Row.ID, ref  c);
        // Info item displayed in the Output window
        ComponentMetaData.FireInformation(0, "Input0_ProcessInputRow()", "Row: " + Row.ID, null, 0, ref c);
        if (Row.ID != null)
        {
            try
            {
                Row.IDEncrypted = EncryptThis((int)Row.ID);
            }
            catch (Exception ex)
            {
                // Error item displayed in the Output window
                ComponentMetaData.FireError(411, "Input0_ProcessInputRow()", "Could not encrypt ID: " + Row.ID, string.Empty, 0, out c);
            }
        }
    }
    
Tagged as: No Comments
2Mar/100

SSIS package deployment and passwords

Something to remember when deploying your SSIS package:

The server will most likely run your package under a different user than the user you used to create the package. This causes a problem with the 'ProtectionLevel'.

The default ProtectionLevel is EncryptSensitiveWithUserKey. During deployment, the user key will not be the same as yours. You need the same keys to encrypt and decrypt the connection strings and stuff like that.

This will give you the error: Failed to decrypt protected XML node "DTS:Password"
This error will only occure when you try to deploy, not while testing locally.

To fix this, change the ProtectionLevel to 'EncryptSensitiveWithPassword'.
ProtectionLevel is found in the properties of the 'Package Explorer' tab.

Then, when you create your job in the SQL Server Agent, you must enter your password.
This is done in the 'Steps' page:
- Under Type select SQL Server Integration Service Package
- Under Run as select SQL Server Agent Service Account
- Under the General tab and Package, select the path to your package (in the bid folder of your project or where ever you put it)
- Click Configurations or any other tab and you will then be prompted to enter your password in a popup.

Tagged as: No Comments
12Feb/100

Temporary tables in SSIS

On one of our projects, we had some SQL that contained a temp table. This temp table is not one that will be used across several Data Flow Tasks. It is only used within a single one.

I don't want to hear the arguments for not using temp tables. Sometimes you just have to. We found ourselves with one of those situations.

After a lot of research and reading of other people's blog posts, I found a solution.

We had been using an OLE DB connection to our database.
Inside our Data Flow Task we placed our SQL inside an OLE DB Source.
None of the suggested solutions I read thru allowed me to use a temp table.

Our solution....

Use an ADO DB connection. Then an ADO NET Source.
Then under the properties of the ADO DB connection, we set
- RetainSameConnection = True
- DelayValidation = True
Most important, we didn't use a temporary table (CREATE TABLE #Res .....). We used a variable table (DECLARE @Res TABLE .....) instead.

That did the trick.

I am glad this worked because I really didn't want to deal with Global tables or defining a global table in the DB ahead of time or any workarounds like that. This was simple and it worked.

For some reason, this won't work with an OLE DB connection. We think we know why, but have not found the documentation it.

Tagged as: , No Comments