Showing posts with label creating. Show all posts
Showing posts with label creating. Show all posts

Friday, March 30, 2012

pros/cons of using Access 2003 as a front-end for SQL 2005

Hi,

I'm creating a SQL 2005 database for a small company. I'm leaning towards using Access 2003 as a front-end for them, since it has a decent report writer and the adp projects seem to preserve SQL's schema relationships.

But I've read some posts where Microsoft is frowning on adp projects. It would cost this company more money in the short-term, but am I better off building a custom .net winforms application instead and avoid Access 2003?

I've done a lot of asp.net coding, but not too much Access or WinForms...so I have a slight learning curve either way.

I've looked at some RAD Tools like Iron Speed Designer, but I'm not sure they'll spend the $$ on that and it seemed complicated to customize the generated code.

thanks,
Bruce
I would recommend to ask this question on access forum instead.

Pros & Cons of Using Triggers

Hello,
Can anyone tell me what are the pros and cons of creating and using triggers
in the database? Are there any performance and debuggins concerns?
TIA,
DeeTriggers are primarily intended for providing procedural integrity, however
they can be used for several purposes. There are no generalized "pros &
cons" per se with triggers, but in specific situations you might come across
performance problems with locking, serialization and concurrency issues.
Anith

Pros & Cons of Using Triggers

Hello,
Can anyone tell me what are the pros and cons of creating and using triggers
in the database? Are there any performance and debuggins concerns?
TIA,
DeeTriggers are primarily intended for providing procedural integrity, however
they can be used for several purposes. There are no generalized "pros &
cons" per se with triggers, but in specific situations you might come across
performance problems with locking, serialization and concurrency issues.
--
Anith

Pros & Cons of Using Triggers

Hello,
Can anyone tell me what are the pros and cons of creating and using triggers
in the database? Are there any performance and debuggins concerns?
TIA,
Dee
Triggers are primarily intended for providing procedural integrity, however
they can be used for several purposes. There are no generalized "pros &
cons" per se with triggers, but in specific situations you might come across
performance problems with locking, serialization and concurrency issues.
Anith
sql

Friday, March 23, 2012

Proper ADO Usage where Conflicts will arise

Hi everyone, I'm creating a ASP.NET 2.0 web application utilizing sql server 2000 as a database. My problem revolves around multiuser acces with long running processes. Some of the pages in the application have long running processes against large tables in the database, lets say that take 2minutes to complete. My problem is how do I utilize ado properly in the rest of my application to display a message to users who may try to access data associated with a table while in the midst of one of its long running processes? For instance I would like to notify the user that "Table X is currently locked, please try again in a few minutes".
Do I catch sqlException and examine the .Number property? Any insight is appreciated.

Thanks.

For Sql server 2005 you can use try /catch to Resolve deadlock:Using TRY/CATCH to Resolve Deadlocks in SQL Server 2005

For sql server 2000 you can take a look at:

Tips for Reducing SQL Server Locks

Troubleshooting Deadlocks

Hope it helps.

|||

Sorry I should add that I'm looking for a way to do this WITHOUT stored procedures. My client does not like using stored procedures (regardless of good idea or not), I'm looking for advice on solutions utilizing C# and ADO.NET set of libraries only.

Thanks

sql

Tuesday, March 20, 2012

Progress Bar in Table Cell

I'm creating a report with several columns. One of which is a percentage
value. The business people have asked that that column show a progress bar of
sorts to give a visual indicator of the percentage complete, in addition to
the textual %. I have tried to figure out how to do this in a table cell but
to no avail. It appears that you can't use an Expression to set the sizing of
an image, rectangle, etc. Anyone have an idea on how this might be done?
Thanks!you could try a chart (one of the bar graphs that are horizontal based).Then
maybe format the chart to remove the legend, scale, title etc
"rSmoke" wrote:
> I'm creating a report with several columns. One of which is a percentage
> value. The business people have asked that that column show a progress bar of
> sorts to give a visual indicator of the percentage complete, in addition to
> the textual %. I have tried to figure out how to do this in a table cell but
> to no avail. It appears that you can't use an Expression to set the sizing of
> an image, rectangle, etc. Anyone have an idea on how this might be done?
> Thanks!|||I had tried that, except you can't put a chart in a table cell. However, your
post led me to try a subreport with a chart in it. That works great. I had
tried a subreport before but hadn't thought to try a chart in it. Thanks for
the help.
"NH" wrote:
> you could try a chart (one of the bar graphs that are horizontal based).Then
> maybe format the chart to remove the legend, scale, title etc
> "rSmoke" wrote:
> > I'm creating a report with several columns. One of which is a percentage
> > value. The business people have asked that that column show a progress bar of
> > sorts to give a visual indicator of the percentage complete, in addition to
> > the textual %. I have tried to figure out how to do this in a table cell but
> > to no avail. It appears that you can't use an Expression to set the sizing of
> > an image, rectangle, etc. Anyone have an idea on how this might be done?
> > Thanks!|||Note: you can put a chart inside a table group header or group footer. In
that case, the chart would be based of all data rows of that particular
group instance (which is what you typically want). The subreport approach
works but is usually not as efficient as table groups.
-- Robert
This posting is provided "AS IS" with no warranties, and confers no rights.
"rSmoke" <rSmoke@.discussions.microsoft.com> wrote in message
news:7CC6307F-077B-45A8-9BBD-18C451815AD4@.microsoft.com...
>I had tried that, except you can't put a chart in a table cell. However,
>your
> post led me to try a subreport with a chart in it. That works great. I had
> tried a subreport before but hadn't thought to try a chart in it. Thanks
> for
> the help.
> "NH" wrote:
>> you could try a chart (one of the bar graphs that are horizontal
>> based).Then
>> maybe format the chart to remove the legend, scale, title etc
>> "rSmoke" wrote:
>> > I'm creating a report with several columns. One of which is a
>> > percentage
>> > value. The business people have asked that that column show a progress
>> > bar of
>> > sorts to give a visual indicator of the percentage complete, in
>> > addition to
>> > the textual %. I have tried to figure out how to do this in a table
>> > cell but
>> > to no avail. It appears that you can't use an Expression to set the
>> > sizing of
>> > an image, rectangle, etc. Anyone have an idea on how this might be
>> > done?
>> > Thanks!

Progress bar for backup operation

Hi,
I am creating a simple form that user will backup his database using that. I
need to show a progress bar when the backup is in progress. How can I read a
value which indicates that? I saw that BACKUP statement has a STATS option,
but I don't know how to capture its value from the server and bring it to
client.
Any help would be greatly appreciated.
Thanks in advance,
Amin
Amin,
Use the Complete event of the Backup object in SQL-DMO.
Mark Allison, SQL Server MVP
http://www.markallison.co.uk
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Amin Sobati wrote:
> Hi,
> I am creating a simple form that user will backup his database using that. I
> need to show a progress bar when the backup is in progress. How can I read a
> value which indicates that? I saw that BACKUP statement has a STATS option,
> but I don't know how to capture its value from the server and bring it to
> client.
> Any help would be greatly appreciated.
> Thanks in advance,
> Amin
>
>
|||Amin,
Oops, I meant use the PercentComplete event of the Backup object. Ignore
my other post in this thread.
Mark Allison, SQL Server MVP
http://www.markallison.co.uk
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Amin Sobati wrote:
> Hi,
> I am creating a simple form that user will backup his database using that. I
> need to show a progress bar when the backup is in progress. How can I read a
> value which indicates that? I saw that BACKUP statement has a STATS option,
> but I don't know how to capture its value from the server and bring it to
> client.
> Any help would be greatly appreciated.
> Thanks in advance,
> Amin
>
>
|||Thanks Mark! That was great tip :-)
"Mark Allison" <marka@.no.tinned.meat.mvps.org> wrote in message
news:OZDT9GabEHA.4092@.TK2MSFTNGP11.phx.gbl...[vbcol=seagreen]
> Amin,
> Oops, I meant use the PercentComplete event of the Backup object. Ignore
> my other post in this thread.
> --
> Mark Allison, SQL Server MVP
> http://www.markallison.co.uk
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
>
> Amin Sobati wrote:
that. I[vbcol=seagreen]
read a[vbcol=seagreen]
option,[vbcol=seagreen]
to[vbcol=seagreen]

Progress bar for backup operation

Hi,
I am creating a simple form that user will backup his database using that. I
need to show a progress bar when the backup is in progress. How can I read a
value which indicates that? I saw that BACKUP statement has a STATS option,
but I don't know how to capture its value from the server and bring it to
client.
Any help would be greatly appreciated.
Thanks in advance,
AminAmin,
Use the Complete event of the Backup object in SQL-DMO.
--
Mark Allison, SQL Server MVP
http://www.markallison.co.uk
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Amin Sobati wrote:
> Hi,
> I am creating a simple form that user will backup his database using that.
I
> need to show a progress bar when the backup is in progress. How can I read
a
> value which indicates that? I saw that BACKUP statement has a STATS option
,
> but I don't know how to capture its value from the server and bring it to
> client.
> Any help would be greatly appreciated.
> Thanks in advance,
> Amin
>
>|||Amin,
Oops, I meant use the PercentComplete event of the Backup object. Ignore
my other post in this thread.
--
Mark Allison, SQL Server MVP
http://www.markallison.co.uk
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Amin Sobati wrote:
> Hi,
> I am creating a simple form that user will backup his database using that.
I
> need to show a progress bar when the backup is in progress. How can I read
a
> value which indicates that? I saw that BACKUP statement has a STATS option
,
> but I don't know how to capture its value from the server and bring it to
> client.
> Any help would be greatly appreciated.
> Thanks in advance,
> Amin
>
>|||Thanks Mark! That was great tip :-)
"Mark Allison" <marka@.no.tinned.meat.mvps.org> wrote in message
news:OZDT9GabEHA.4092@.TK2MSFTNGP11.phx.gbl...[vbcol=seagreen]
> Amin,
> Oops, I meant use the PercentComplete event of the Backup object. Ignore
> my other post in this thread.
> --
> Mark Allison, SQL Server MVP
> http://www.markallison.co.uk
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
>
> Amin Sobati wrote:
that. I[vbcol=seagreen]
read a[vbcol=seagreen]
option,[vbcol=seagreen]
to[vbcol=seagreen]

Progress bar for backup operation

Hi,
I am creating a simple form that user will backup his database using that. I
need to show a progress bar when the backup is in progress. How can I read a
value which indicates that? I saw that BACKUP statement has a STATS option,
but I don't know how to capture its value from the server and bring it to
client.
Any help would be greatly appreciated.
Thanks in advance,
AminAmin,
Use the Complete event of the Backup object in SQL-DMO.
--
Mark Allison, SQL Server MVP
http://www.markallison.co.uk
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Amin Sobati wrote:
> Hi,
> I am creating a simple form that user will backup his database using that. I
> need to show a progress bar when the backup is in progress. How can I read a
> value which indicates that? I saw that BACKUP statement has a STATS option,
> but I don't know how to capture its value from the server and bring it to
> client.
> Any help would be greatly appreciated.
> Thanks in advance,
> Amin
>
>|||Amin,
Oops, I meant use the PercentComplete event of the Backup object. Ignore
my other post in this thread.
--
Mark Allison, SQL Server MVP
http://www.markallison.co.uk
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Amin Sobati wrote:
> Hi,
> I am creating a simple form that user will backup his database using that. I
> need to show a progress bar when the backup is in progress. How can I read a
> value which indicates that? I saw that BACKUP statement has a STATS option,
> but I don't know how to capture its value from the server and bring it to
> client.
> Any help would be greatly appreciated.
> Thanks in advance,
> Amin
>
>|||Thanks Mark! That was great tip :-)
"Mark Allison" <marka@.no.tinned.meat.mvps.org> wrote in message
news:OZDT9GabEHA.4092@.TK2MSFTNGP11.phx.gbl...
> Amin,
> Oops, I meant use the PercentComplete event of the Backup object. Ignore
> my other post in this thread.
> --
> Mark Allison, SQL Server MVP
> http://www.markallison.co.uk
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
>
> Amin Sobati wrote:
> > Hi,
> > I am creating a simple form that user will backup his database using
that. I
> > need to show a progress bar when the backup is in progress. How can I
read a
> > value which indicates that? I saw that BACKUP statement has a STATS
option,
> > but I don't know how to capture its value from the server and bring it
to
> > client.
> > Any help would be greatly appreciated.
> > Thanks in advance,
> > Amin
> >
> >
> >

Friday, March 9, 2012

Programmatically creating Transformation Script Component

Does anyone have any examples of programmatically creating a Transformation Script Component (or Source/Destination) in the dataflow? I have been able to create other Transforms for the dataflow like Derived Column, Sort, etc. but for some reason the Script Component doesn't seem to work the same way.

I have done it as below trying many ways to get the componentClassId including the AssemblyQualifiedname & the GUID as well. No matter, what I do, when it hits the ProvideComponentProperties, it get Exception from HRESULT: 0xC0048021

IDTSComponentMetaData90 scriptPropType = dataFlow.ComponentMetaDataCollection.New();

scriptPropType.Name = "Transform Property Type";

scriptPropType.ComponentClassID = "DTSTransform.ScriptComponent";

// have also tried scriptPropType.ComponentClassID =typeof(Microsoft.SqlServer.Dts.Pipeline.ScriptComponent).AssemblyQualifiedName;

scriptPropType.Description = "Transform Property Type";

CManagedComponentWrapper instance2 = scriptPropType.Instantiate();

instance2.ProvideComponentProperties();

Any help or examples would be greatly appreciated! Thanks!

If you have not deduced, the error 0xC0048021 means that the component is not installed basically, so I'd say whatever you are using for the ComponentClassID is not right as you suspect. (http://wiki.sqlis.com/default.aspx/SQLISWiki/0xC0048021.html)

As a start point, what values have you tried., and did they include this -

Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost, Microsoft.SqlServer.TxScript, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

Is that assembly in the GAC?

|||

thanks! worked like a charm.

Now...I have the inputs selected and the outputs added but can't figure out how to add the actual script code. I don't see any custom properties that look like a script. I know I have to override the ScriptMain routines, just not sure how.

Again any help or examples would be great. thanks

|||

Can you find a SourceCode property? Looking in Books Online, it seems that MS have pretty much neglected to document the component object model, and even in the limited component property documentation (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/dtsref9/html/56f5df6a-56f6-43df-bca9-08476a3bd931.htm#script) this property is not listed. I’d say they just have not documented this at all, so is it even supported? A think it is rather pants if you cannot build packages entirely in code. Still, have a look at the SourceCode property, and perhaps have a look at what it is if you load an existing package via the object model. Another place to look is the raw XML of an existing DTSX file, but bare in mind this has been XML encoded in various unknown ways and may not be the directly assignable as you see the Xml, hence I suggested looking at an existing component through the object model.

|||

Yes, found the SourceCode custom property after last post, but am having lots of trouble figuring out what to put in there.

I am comparing the XML of the a package where the script was created through bids vs the script I'm trying to create programmatically. In Bids, It goes from an arrayElementCount of 0 with the default script to an arrayElementCount of 4 once you make change to the script. It adds an element for a .vsaproj, an element for the references, an element for .vsaitem. No clue how to add those items. I can see that the Script Task on the Control Flow does something similiar but has built in routines SetUniqueVsaProjectName & CodeProvider.PutSourceCode. So far, I'm not finding the corresponding routines for the Script Component. Any clues on that? thanks

|||

I've been doing some playing with this. The value of SourceCode is just a string array, so you can easily create a this array to set it. There are four items in the array as you note. They seem to be in pairs, a moniker and some detail. You can examine these in detail for yourself, but the monikers seem to be a standard format and, and even the project xml seems fairly sensible, then you just have the VB.Net code. So far there is nothing that could not be easily derived, even the moniker and project format just uses a Guid, albeit formatted ( Guid.ToString("n") ).

The major issue is that you also need to supply the wrapper code. Look in the project Xml (array element 1, or the second item) and you will see if references 3 files, only one of which is ScriptMain, the code we normally write. The other two are the wrappers. You can see these in the VSA designer if you look, but they are auto-generated at design-time for you.

So without these wrappers our basic code will never compile. This of course raises the issue of compilation. Normally the PreCompile property is true, so the designer compiles the code. This ends up as base 64 encoded string in another property, BinaryCode (?).

We can access the VSA compilation engine, and may even be able to get the compiled code back as binary, so we can base64 encode and set the property, but we still lack the wrappers. These seem like a lot of hard work, it seems MS generates them, but in sealed/internal design-time modules. So maybe we just write our own wrappers? Possible, but this means the package will not be maintainable via the UI. Is that an issue?

|||

Thanks for looking into it. We were on the same track. We did get the script component to work but had to set the Precompile to false. Since we are going to be running it on 64bit, that won't work for us. We need to set the property "BinaryCode" to the compiled code. Looking into ways to get the binary code. But we are also pursuing building custom components instead of script components.

String[] scriptValue = newString[4];

scriptValue[0] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @.".vsaproj";

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

scriptValue[2] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/ScriptMain.vsaitem";

scriptValue[3] = "' Microsoft SQL Server Integration Services user script component\r\n"

+ "' This is your new script component in Microsoft Visual Basic .NET \r\n"

+ "' ScriptMain is the entrypoint class for script components\r\n"

+ "\r\n"

+ "Imports System \r\n"

+ "Imports System.Data \r\n"

+ "Imports System.Math \r\n"

+ "Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper \r\n"

+ "Imports Microsoft.SqlServer.Dts.Runtime.Wrapper \r\n"

+ " \r\n"

+ "Public Class ScriptMain \r\n"

+ " Inherits UserComponent \r\n"

+ " \r\n"

+ " Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer) \r\n"

+ " ' \r\n"

+ " 'Code Here \r\n"

+ " ' \r\n"

+ " End Sub \r\n"

+ " \r\n"

+ "End Class \r\n";

IDTSDesigntimeComponent90 anIDTSDesigntimeComponent90 = instance2 asIDTSDesigntimeComponent90;

anIDTSDesigntimeComponent90.SetComponentProperty("SourceCode", scriptValue);

anIDTSDesigntimeComponent90.SetComponentProperty("PreCompile", false);

|||Yep the 64bit will be a killer for you. Whilst it is possible to genarete your own wrappers, custom components may well be easier. To be honest you could probably write your own component that accepted .Net code, easier than you can simulate the stock component. If the code is reasonably static custom components would be easier, I find them easier anyway.|||

You have done very good investigation. Could you please post full example of how youprogrammatically created a Transformation Script Component. I have a similar task and would appreciate your help.

|||

I'm also trying to generate a script component programmatically and this post has been very useful, just about the only info I could find on it.

I've followed through what's above and incorporated this into my own project, but I'm stuck with this bit (from the above):

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

I'm guessing this somehow adds the references in - but I can't find the "Properties" of (I'm assuming) the namespace of the package generation class. Can anyone help here? Sounds like ProjectFile is a member ofCreateTemporaryVCProject - buried deep in the framework and a little short on documentation.

I'm also concerned about the need to supply the wrapper files as discussed. Did you manage to get around this or would it still be necessary to supply these; even once you've added the XML resources I refer to above? If so I reckon I may have to take the plunge with custom components.

|||

ConsoleApplication1.Properties.Resources.ProjectFile refers to a property called ProjectFile in the application CarlaC wrote. That is basically a string resource. Look at the Resources tab in your Visual Studio Project, or have a look in the MSDN docs on this.

It is not really important, what is important is the XML that that property contained. As per the name and my description above, it is the "project file", the XML stuff a bit like what you see if you open a csproj in notepad now. The project file will hold the references, and other project level infromation. The best thing to do would be to reverse engineer a package you built in the designer. That is what I did, and to be honest I just don't think this is feasible. So I only spent a few hours on the topic, but there was an awfull lot of code generation logic embeded in the UI that you cannot access. Damn internal methods, seaaled classes etc, and decompiling code to that degree, yuk.

Personally I think this is just too much work. I would find it easier to write my own components. Forget the dynamic stuff, it is too much work, and I cannot see anyone getting eneough reuse from such effort.

|||

CarlaC,

Not sure if you got the answers you were looking for, it's been a while since you posted this message. However, I'm working on a similar scenario and have found the exact solution for creating a script task and embedding the code in it.

To make this all work...

1. Create a new package in the designer and add the script object (and associated code).

2. Right-click on the package and select "View Code"

3. Within the XML will be two "CDATA" tags, one starting with "<VisualStudioProject>" and the other starting with "' Microsoft SQL Server Integration Services Script Task".

4. Go to the project you are creating to build your script task, I have chosen to add two string variables to the resource file which are used to hold the script in both tags mentioned above (i.e. "ScriptTaskCode" and "ScriptTaskProjFile").

5. Once you have set the two properties in your resource file (or in the local code page) you can then use the following code to load the scripts into the script component:

'NOTE: You will need a reference to the following in your class:

'C:\Program Files\Microsoft SQL Server\90\DTS\Binn\Microsoft.SqlServer.VSAHosting.dll

'C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.ScriptTask.dll

'add a scripting task to the package

scriptTaskHost = TryCast(Me.m_pkg.Executables.Add("STOCKTongue TiedCRIPTTASK"), TaskHost)

scriptTaskHost.Properties("Name").SetValue(scriptTaskHost, "PkgUpdate")

scriptTaskHost.Properties("Description").SetValue(scriptTaskHost, "PkgUpdate")

'load the script task code from the resource file

scriptTask = TryCast(scriptTaskHost.InnerObject, ScriptTask)

scriptTask.SetUniqueVsaProjectName()

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/ScriptMain.vsaitem", My.Resources.ScriptTaskCode)

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/" & scriptTask.VsaProjectName & ".vsaproj", My.Resources.ScriptTaskProjFile)

scriptTask.PreCompile = False

'save everything

ssisApp = New Application()

ssisApp.SaveToDtsServer(Me.m_pkg, Nothing, "MSDB\" & Me.m_pkg.Name, serverName)

|||Have any of you managed to create a Source Script Component programmatically. I seem to only be able to create Transformation Script Components. Thanks.

Programmatically creating Transformation Script Component

Does anyone have any examples of programmatically creating a Transformation Script Component (or Source/Destination) in the dataflow? I have been able to create other Transforms for the dataflow like Derived Column, Sort, etc. but for some reason the Script Component doesn't seem to work the same way.

I have done it as below trying many ways to get the componentClassId including the AssemblyQualifiedname & the GUID as well. No matter, what I do, when it hits the ProvideComponentProperties, it get Exception from HRESULT: 0xC0048021

IDTSComponentMetaData90 scriptPropType = dataFlow.ComponentMetaDataCollection.New();

scriptPropType.Name = "Transform Property Type";

scriptPropType.ComponentClassID = "DTSTransform.ScriptComponent";

// have also tried scriptPropType.ComponentClassID =typeof(Microsoft.SqlServer.Dts.Pipeline.ScriptComponent).AssemblyQualifiedName;

scriptPropType.Description = "Transform Property Type";

CManagedComponentWrapper instance2 = scriptPropType.Instantiate();

instance2.ProvideComponentProperties();

Any help or examples would be greatly appreciated! Thanks!

If you have not deduced, the error 0xC0048021 means that the component is not installed basically, so I'd say whatever you are using for the ComponentClassID is not right as you suspect. (http://wiki.sqlis.com/default.aspx/SQLISWiki/0xC0048021.html)

As a start point, what values have you tried., and did they include this -

Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost, Microsoft.SqlServer.TxScript, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

Is that assembly in the GAC?

|||

thanks! worked like a charm.

Now...I have the inputs selected and the outputs added but can't figure out how to add the actual script code. I don't see any custom properties that look like a script. I know I have to override the ScriptMain routines, just not sure how.

Again any help or examples would be great. thanks

|||

Can you find a SourceCode property? Looking in Books Online, it seems that MS have pretty much neglected to document the component object model, and even in the limited component property documentation (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/dtsref9/html/56f5df6a-56f6-43df-bca9-08476a3bd931.htm#script) this property is not listed. I’d say they just have not documented this at all, so is it even supported? A think it is rather pants if you cannot build packages entirely in code. Still, have a look at the SourceCode property, and perhaps have a look at what it is if you load an existing package via the object model. Another place to look is the raw XML of an existing DTSX file, but bare in mind this has been XML encoded in various unknown ways and may not be the directly assignable as you see the Xml, hence I suggested looking at an existing component through the object model.

|||

Yes, found the SourceCode custom property after last post, but am having lots of trouble figuring out what to put in there.

I am comparing the XML of the a package where the script was created through bids vs the script I'm trying to create programmatically. In Bids, It goes from an arrayElementCount of 0 with the default script to an arrayElementCount of 4 once you make change to the script. It adds an element for a .vsaproj, an element for the references, an element for .vsaitem. No clue how to add those items. I can see that the Script Task on the Control Flow does something similiar but has built in routines SetUniqueVsaProjectName & CodeProvider.PutSourceCode. So far, I'm not finding the corresponding routines for the Script Component. Any clues on that? thanks

|||

I've been doing some playing with this. The value of SourceCode is just a string array, so you can easily create a this array to set it. There are four items in the array as you note. They seem to be in pairs, a moniker and some detail. You can examine these in detail for yourself, but the monikers seem to be a standard format and, and even the project xml seems fairly sensible, then you just have the VB.Net code. So far there is nothing that could not be easily derived, even the moniker and project format just uses a Guid, albeit formatted ( Guid.ToString("n") ).

The major issue is that you also need to supply the wrapper code. Look in the project Xml (array element 1, or the second item) and you will see if references 3 files, only one of which is ScriptMain, the code we normally write. The other two are the wrappers. You can see these in the VSA designer if you look, but they are auto-generated at design-time for you.

So without these wrappers our basic code will never compile. This of course raises the issue of compilation. Normally the PreCompile property is true, so the designer compiles the code. This ends up as base 64 encoded string in another property, BinaryCode (?).

We can access the VSA compilation engine, and may even be able to get the compiled code back as binary, so we can base64 encode and set the property, but we still lack the wrappers. These seem like a lot of hard work, it seems MS generates them, but in sealed/internal design-time modules. So maybe we just write our own wrappers? Possible, but this means the package will not be maintainable via the UI. Is that an issue?

|||

Thanks for looking into it. We were on the same track. We did get the script component to work but had to set the Precompile to false. Since we are going to be running it on 64bit, that won't work for us. We need to set the property "BinaryCode" to the compiled code. Looking into ways to get the binary code. But we are also pursuing building custom components instead of script components.

String[] scriptValue = new String[4];

scriptValue[0] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @.".vsaproj";

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

scriptValue[2] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/ScriptMain.vsaitem";

scriptValue[3] = "' Microsoft SQL Server Integration Services user script component\r\n"

+ "' This is your new script component in Microsoft Visual Basic .NET \r\n"

+ "' ScriptMain is the entrypoint class for script components\r\n"

+ "\r\n"

+ "Imports System \r\n"

+ "Imports System.Data \r\n"

+ "Imports System.Math \r\n"

+ "Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper \r\n"

+ "Imports Microsoft.SqlServer.Dts.Runtime.Wrapper \r\n"

+ " \r\n"

+ "Public Class ScriptMain \r\n"

+ " Inherits UserComponent \r\n"

+ " \r\n"

+ " Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer) \r\n"

+ " ' \r\n"

+ " 'Code Here \r\n"

+ " ' \r\n"

+ " End Sub \r\n"

+ " \r\n"

+ "End Class \r\n";

IDTSDesigntimeComponent90 anIDTSDesigntimeComponent90 = instance2 as IDTSDesigntimeComponent90;

anIDTSDesigntimeComponent90.SetComponentProperty("SourceCode", scriptValue);

anIDTSDesigntimeComponent90.SetComponentProperty("PreCompile", false);

|||Yep the 64bit will be a killer for you. Whilst it is possible to genarete your own wrappers, custom components may well be easier. To be honest you could probably write your own component that accepted .Net code, easier than you can simulate the stock component. If the code is reasonably static custom components would be easier, I find them easier anyway.|||

You have done very good investigation. Could you please post full example of how you programmatically created a Transformation Script Component. I have a similar task and would appreciate your help.

|||

I'm also trying to generate a script component programmatically and this post has been very useful, just about the only info I could find on it.

I've followed through what's above and incorporated this into my own project, but I'm stuck with this bit (from the above):

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

I'm guessing this somehow adds the references in - but I can't find the "Properties" of (I'm assuming) the namespace of the package generation class. Can anyone help here? Sounds like ProjectFile is a member of CreateTemporaryVCProject - buried deep in the framework and a little short on documentation.

I'm also concerned about the need to supply the wrapper files as discussed. Did you manage to get around this or would it still be necessary to supply these; even once you've added the XML resources I refer to above? If so I reckon I may have to take the plunge with custom components.

|||

ConsoleApplication1.Properties.Resources.ProjectFile refers to a property called ProjectFile in the application CarlaC wrote. That is basically a string resource. Look at the Resources tab in your Visual Studio Project, or have a look in the MSDN docs on this.

It is not really important, what is important is the XML that that property contained. As per the name and my description above, it is the "project file", the XML stuff a bit like what you see if you open a csproj in notepad now. The project file will hold the references, and other project level infromation. The best thing to do would be to reverse engineer a package you built in the designer. That is what I did, and to be honest I just don't think this is feasible. So I only spent a few hours on the topic, but there was an awfull lot of code generation logic embeded in the UI that you cannot access. Damn internal methods, seaaled classes etc, and decompiling code to that degree, yuk.

Personally I think this is just too much work. I would find it easier to write my own components. Forget the dynamic stuff, it is too much work, and I cannot see anyone getting eneough reuse from such effort.

|||

CarlaC,

Not sure if you got the answers you were looking for, it's been a while since you posted this message. However, I'm working on a similar scenario and have found the exact solution for creating a script task and embedding the code in it.

To make this all work...

1. Create a new package in the designer and add the script object (and associated code).

2. Right-click on the package and select "View Code"

3. Within the XML will be two "CDATA" tags, one starting with "<VisualStudioProject>" and the other starting with "' Microsoft SQL Server Integration Services Script Task".

4. Go to the project you are creating to build your script task, I have chosen to add two string variables to the resource file which are used to hold the script in both tags mentioned above (i.e. "ScriptTaskCode" and "ScriptTaskProjFile").

5. Once you have set the two properties in your resource file (or in the local code page) you can then use the following code to load the scripts into the script component:

'NOTE: You will need a reference to the following in your class:

'C:\Program Files\Microsoft SQL Server\90\DTS\Binn\Microsoft.SqlServer.VSAHosting.dll

'C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.ScriptTask.dll

'add a scripting task to the package

scriptTaskHost = TryCast(Me.m_pkg.Executables.Add("STOCKTongue TiedCRIPTTASK"), TaskHost)

scriptTaskHost.Properties("Name").SetValue(scriptTaskHost, "PkgUpdate")

scriptTaskHost.Properties("Description").SetValue(scriptTaskHost, "PkgUpdate")

'load the script task code from the resource file

scriptTask = TryCast(scriptTaskHost.InnerObject, ScriptTask)

scriptTask.SetUniqueVsaProjectName()

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/ScriptMain.vsaitem", My.Resources.ScriptTaskCode)

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/" & scriptTask.VsaProjectName & ".vsaproj", My.Resources.ScriptTaskProjFile)

scriptTask.PreCompile = False

'save everything

ssisApp = New Application()

ssisApp.SaveToDtsServer(Me.m_pkg, Nothing, "MSDB\" & Me.m_pkg.Name, serverName)

|||Have any of you managed to create a Source Script Component programmatically. I seem to only be able to create Transformation Script Components. Thanks.

Programmatically creating Transformation Script Component

Does anyone have any examples of programmatically creating a Transformation Script Component (or Source/Destination) in the dataflow? I have been able to create other Transforms for the dataflow like Derived Column, Sort, etc. but for some reason the Script Component doesn't seem to work the same way.

I have done it as below trying many ways to get the componentClassId including the AssemblyQualifiedname & the GUID as well. No matter, what I do, when it hits the ProvideComponentProperties, it get Exception from HRESULT: 0xC0048021

IDTSComponentMetaData90 scriptPropType = dataFlow.ComponentMetaDataCollection.New();

scriptPropType.Name = "Transform Property Type";

scriptPropType.ComponentClassID = "DTSTransform.ScriptComponent";

// have also tried scriptPropType.ComponentClassID =typeof(Microsoft.SqlServer.Dts.Pipeline.ScriptComponent).AssemblyQualifiedName;

scriptPropType.Description = "Transform Property Type";

CManagedComponentWrapper instance2 = scriptPropType.Instantiate();

instance2.ProvideComponentProperties();

Any help or examples would be greatly appreciated! Thanks!

If you have not deduced, the error 0xC0048021 means that the component is not installed basically, so I'd say whatever you are using for the ComponentClassID is not right as you suspect. (http://wiki.sqlis.com/default.aspx/SQLISWiki/0xC0048021.html)

As a start point, what values have you tried., and did they include this -

Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost, Microsoft.SqlServer.TxScript, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

Is that assembly in the GAC?

|||

thanks! worked like a charm.

Now...I have the inputs selected and the outputs added but can't figure out how to add the actual script code. I don't see any custom properties that look like a script. I know I have to override the ScriptMain routines, just not sure how.

Again any help or examples would be great. thanks

|||

Can you find a SourceCode property? Looking in Books Online, it seems that MS have pretty much neglected to document the component object model, and even in the limited component property documentation (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/dtsref9/html/56f5df6a-56f6-43df-bca9-08476a3bd931.htm#script) this property is not listed. I’d say they just have not documented this at all, so is it even supported? A think it is rather pants if you cannot build packages entirely in code. Still, have a look at the SourceCode property, and perhaps have a look at what it is if you load an existing package via the object model. Another place to look is the raw XML of an existing DTSX file, but bare in mind this has been XML encoded in various unknown ways and may not be the directly assignable as you see the Xml, hence I suggested looking at an existing component through the object model.

|||

Yes, found the SourceCode custom property after last post, but am having lots of trouble figuring out what to put in there.

I am comparing the XML of the a package where the script was created through bids vs the script I'm trying to create programmatically. In Bids, It goes from an arrayElementCount of 0 with the default script to an arrayElementCount of 4 once you make change to the script. It adds an element for a .vsaproj, an element for the references, an element for .vsaitem. No clue how to add those items. I can see that the Script Task on the Control Flow does something similiar but has built in routines SetUniqueVsaProjectName & CodeProvider.PutSourceCode. So far, I'm not finding the corresponding routines for the Script Component. Any clues on that? thanks

|||

I've been doing some playing with this. The value of SourceCode is just a string array, so you can easily create a this array to set it. There are four items in the array as you note. They seem to be in pairs, a moniker and some detail. You can examine these in detail for yourself, but the monikers seem to be a standard format and, and even the project xml seems fairly sensible, then you just have the VB.Net code. So far there is nothing that could not be easily derived, even the moniker and project format just uses a Guid, albeit formatted ( Guid.ToString("n") ).

The major issue is that you also need to supply the wrapper code. Look in the project Xml (array element 1, or the second item) and you will see if references 3 files, only one of which is ScriptMain, the code we normally write. The other two are the wrappers. You can see these in the VSA designer if you look, but they are auto-generated at design-time for you.

So without these wrappers our basic code will never compile. This of course raises the issue of compilation. Normally the PreCompile property is true, so the designer compiles the code. This ends up as base 64 encoded string in another property, BinaryCode (?).

We can access the VSA compilation engine, and may even be able to get the compiled code back as binary, so we can base64 encode and set the property, but we still lack the wrappers. These seem like a lot of hard work, it seems MS generates them, but in sealed/internal design-time modules. So maybe we just write our own wrappers? Possible, but this means the package will not be maintainable via the UI. Is that an issue?

|||

Thanks for looking into it. We were on the same track. We did get the script component to work but had to set the Precompile to false. Since we are going to be running it on 64bit, that won't work for us. We need to set the property "BinaryCode" to the compiled code. Looking into ways to get the binary code. But we are also pursuing building custom components instead of script components.

String[] scriptValue = new String[4];

scriptValue[0] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @.".vsaproj";

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

scriptValue[2] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/ScriptMain.vsaitem";

scriptValue[3] = "' Microsoft SQL Server Integration Services user script component\r\n"

+ "' This is your new script component in Microsoft Visual Basic .NET \r\n"

+ "' ScriptMain is the entrypoint class for script components\r\n"

+ "\r\n"

+ "Imports System \r\n"

+ "Imports System.Data \r\n"

+ "Imports System.Math \r\n"

+ "Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper \r\n"

+ "Imports Microsoft.SqlServer.Dts.Runtime.Wrapper \r\n"

+ " \r\n"

+ "Public Class ScriptMain \r\n"

+ " Inherits UserComponent \r\n"

+ " \r\n"

+ " Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer) \r\n"

+ " ' \r\n"

+ " 'Code Here \r\n"

+ " ' \r\n"

+ " End Sub \r\n"

+ " \r\n"

+ "End Class \r\n";

IDTSDesigntimeComponent90 anIDTSDesigntimeComponent90 = instance2 as IDTSDesigntimeComponent90;

anIDTSDesigntimeComponent90.SetComponentProperty("SourceCode", scriptValue);

anIDTSDesigntimeComponent90.SetComponentProperty("PreCompile", false);

|||Yep the 64bit will be a killer for you. Whilst it is possible to genarete your own wrappers, custom components may well be easier. To be honest you could probably write your own component that accepted .Net code, easier than you can simulate the stock component. If the code is reasonably static custom components would be easier, I find them easier anyway.|||

You have done very good investigation. Could you please post full example of how you programmatically created a Transformation Script Component. I have a similar task and would appreciate your help.

|||

I'm also trying to generate a script component programmatically and this post has been very useful, just about the only info I could find on it.

I've followed through what's above and incorporated this into my own project, but I'm stuck with this bit (from the above):

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

I'm guessing this somehow adds the references in - but I can't find the "Properties" of (I'm assuming) the namespace of the package generation class. Can anyone help here? Sounds like ProjectFile is a member of CreateTemporaryVCProject - buried deep in the framework and a little short on documentation.

I'm also concerned about the need to supply the wrapper files as discussed. Did you manage to get around this or would it still be necessary to supply these; even once you've added the XML resources I refer to above? If so I reckon I may have to take the plunge with custom components.

|||

ConsoleApplication1.Properties.Resources.ProjectFile refers to a property called ProjectFile in the application CarlaC wrote. That is basically a string resource. Look at the Resources tab in your Visual Studio Project, or have a look in the MSDN docs on this.

It is not really important, what is important is the XML that that property contained. As per the name and my description above, it is the "project file", the XML stuff a bit like what you see if you open a csproj in notepad now. The project file will hold the references, and other project level infromation. The best thing to do would be to reverse engineer a package you built in the designer. That is what I did, and to be honest I just don't think this is feasible. So I only spent a few hours on the topic, but there was an awfull lot of code generation logic embeded in the UI that you cannot access. Damn internal methods, seaaled classes etc, and decompiling code to that degree, yuk.

Personally I think this is just too much work. I would find it easier to write my own components. Forget the dynamic stuff, it is too much work, and I cannot see anyone getting eneough reuse from such effort.

|||

CarlaC,

Not sure if you got the answers you were looking for, it's been a while since you posted this message. However, I'm working on a similar scenario and have found the exact solution for creating a script task and embedding the code in it.

To make this all work...

1. Create a new package in the designer and add the script object (and associated code).

2. Right-click on the package and select "View Code"

3. Within the XML will be two "CDATA" tags, one starting with "<VisualStudioProject>" and the other starting with "' Microsoft SQL Server Integration Services Script Task".

4. Go to the project you are creating to build your script task, I have chosen to add two string variables to the resource file which are used to hold the script in both tags mentioned above (i.e. "ScriptTaskCode" and "ScriptTaskProjFile").

5. Once you have set the two properties in your resource file (or in the local code page) you can then use the following code to load the scripts into the script component:

'NOTE: You will need a reference to the following in your class:

'C:\Program Files\Microsoft SQL Server\90\DTS\Binn\Microsoft.SqlServer.VSAHosting.dll

'C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.ScriptTask.dll

'add a scripting task to the package

scriptTaskHost = TryCast(Me.m_pkg.Executables.Add("STOCKTongue TiedCRIPTTASK"), TaskHost)

scriptTaskHost.Properties("Name").SetValue(scriptTaskHost, "PkgUpdate")

scriptTaskHost.Properties("Description").SetValue(scriptTaskHost, "PkgUpdate")

'load the script task code from the resource file

scriptTask = TryCast(scriptTaskHost.InnerObject, ScriptTask)

scriptTask.SetUniqueVsaProjectName()

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/ScriptMain.vsaitem", My.Resources.ScriptTaskCode)

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/" & scriptTask.VsaProjectName & ".vsaproj", My.Resources.ScriptTaskProjFile)

scriptTask.PreCompile = False

'save everything

ssisApp = New Application()

ssisApp.SaveToDtsServer(Me.m_pkg, Nothing, "MSDB\" & Me.m_pkg.Name, serverName)

|||Have any of you managed to create a Source Script Component programmatically. I seem to only be able to create Transformation Script Components. Thanks.

Programmatically creating Transformation Script Component

Does anyone have any examples of programmatically creating a Transformation Script Component (or Source/Destination) in the dataflow? I have been able to create other Transforms for the dataflow like Derived Column, Sort, etc. but for some reason the Script Component doesn't seem to work the same way.

I have done it as below trying many ways to get the componentClassId including the AssemblyQualifiedname & the GUID as well. No matter, what I do, when it hits the ProvideComponentProperties, it get Exception from HRESULT: 0xC0048021

IDTSComponentMetaData90 scriptPropType = dataFlow.ComponentMetaDataCollection.New();

scriptPropType.Name = "Transform Property Type";

scriptPropType.ComponentClassID = "DTSTransform.ScriptComponent";

// have also tried scriptPropType.ComponentClassID =typeof(Microsoft.SqlServer.Dts.Pipeline.ScriptComponent).AssemblyQualifiedName;

scriptPropType.Description = "Transform Property Type";

CManagedComponentWrapper instance2 = scriptPropType.Instantiate();

instance2.ProvideComponentProperties();

Any help or examples would be greatly appreciated! Thanks!

If you have not deduced, the error 0xC0048021 means that the component is not installed basically, so I'd say whatever you are using for the ComponentClassID is not right as you suspect. (http://wiki.sqlis.com/default.aspx/SQLISWiki/0xC0048021.html)

As a start point, what values have you tried., and did they include this -

Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost, Microsoft.SqlServer.TxScript, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

Is that assembly in the GAC?

|||

thanks! worked like a charm.

Now...I have the inputs selected and the outputs added but can't figure out how to add the actual script code. I don't see any custom properties that look like a script. I know I have to override the ScriptMain routines, just not sure how.

Again any help or examples would be great. thanks

|||

Can you find a SourceCode property? Looking in Books Online, it seems that MS have pretty much neglected to document the component object model, and even in the limited component property documentation (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/dtsref9/html/56f5df6a-56f6-43df-bca9-08476a3bd931.htm#script) this property is not listed. I’d say they just have not documented this at all, so is it even supported? A think it is rather pants if you cannot build packages entirely in code. Still, have a look at the SourceCode property, and perhaps have a look at what it is if you load an existing package via the object model. Another place to look is the raw XML of an existing DTSX file, but bare in mind this has been XML encoded in various unknown ways and may not be the directly assignable as you see the Xml, hence I suggested looking at an existing component through the object model.

|||

Yes, found the SourceCode custom property after last post, but am having lots of trouble figuring out what to put in there.

I am comparing the XML of the a package where the script was created through bids vs the script I'm trying to create programmatically. In Bids, It goes from an arrayElementCount of 0 with the default script to an arrayElementCount of 4 once you make change to the script. It adds an element for a .vsaproj, an element for the references, an element for .vsaitem. No clue how to add those items. I can see that the Script Task on the Control Flow does something similiar but has built in routines SetUniqueVsaProjectName & CodeProvider.PutSourceCode. So far, I'm not finding the corresponding routines for the Script Component. Any clues on that? thanks

|||

I've been doing some playing with this. The value of SourceCode is just a string array, so you can easily create a this array to set it. There are four items in the array as you note. They seem to be in pairs, a moniker and some detail. You can examine these in detail for yourself, but the monikers seem to be a standard format and, and even the project xml seems fairly sensible, then you just have the VB.Net code. So far there is nothing that could not be easily derived, even the moniker and project format just uses a Guid, albeit formatted ( Guid.ToString("n") ).

The major issue is that you also need to supply the wrapper code. Look in the project Xml (array element 1, or the second item) and you will see if references 3 files, only one of which is ScriptMain, the code we normally write. The other two are the wrappers. You can see these in the VSA designer if you look, but they are auto-generated at design-time for you.

So without these wrappers our basic code will never compile. This of course raises the issue of compilation. Normally the PreCompile property is true, so the designer compiles the code. This ends up as base 64 encoded string in another property, BinaryCode (?).

We can access the VSA compilation engine, and may even be able to get the compiled code back as binary, so we can base64 encode and set the property, but we still lack the wrappers. These seem like a lot of hard work, it seems MS generates them, but in sealed/internal design-time modules. So maybe we just write our own wrappers? Possible, but this means the package will not be maintainable via the UI. Is that an issue?

|||

Thanks for looking into it. We were on the same track. We did get the script component to work but had to set the Precompile to false. Since we are going to be running it on 64bit, that won't work for us. We need to set the property "BinaryCode" to the compiled code. Looking into ways to get the binary code. But we are also pursuing building custom components instead of script components.

String[] scriptValue = new String[4];

scriptValue[0] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @.".vsaproj";

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

scriptValue[2] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/ScriptMain.vsaitem";

scriptValue[3] = "' Microsoft SQL Server Integration Services user script component\r\n"

+ "' This is your new script component in Microsoft Visual Basic .NET \r\n"

+ "' ScriptMain is the entrypoint class for script components\r\n"

+ "\r\n"

+ "Imports System \r\n"

+ "Imports System.Data \r\n"

+ "Imports System.Math \r\n"

+ "Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper \r\n"

+ "Imports Microsoft.SqlServer.Dts.Runtime.Wrapper \r\n"

+ " \r\n"

+ "Public Class ScriptMain \r\n"

+ " Inherits UserComponent \r\n"

+ " \r\n"

+ " Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer) \r\n"

+ " ' \r\n"

+ " 'Code Here \r\n"

+ " ' \r\n"

+ " End Sub \r\n"

+ " \r\n"

+ "End Class \r\n";

IDTSDesigntimeComponent90 anIDTSDesigntimeComponent90 = instance2 as IDTSDesigntimeComponent90;

anIDTSDesigntimeComponent90.SetComponentProperty("SourceCode", scriptValue);

anIDTSDesigntimeComponent90.SetComponentProperty("PreCompile", false);

|||Yep the 64bit will be a killer for you. Whilst it is possible to genarete your own wrappers, custom components may well be easier. To be honest you could probably write your own component that accepted .Net code, easier than you can simulate the stock component. If the code is reasonably static custom components would be easier, I find them easier anyway.|||

You have done very good investigation. Could you please post full example of how you programmatically created a Transformation Script Component. I have a similar task and would appreciate your help.

|||

I'm also trying to generate a script component programmatically and this post has been very useful, just about the only info I could find on it.

I've followed through what's above and incorporated this into my own project, but I'm stuck with this bit (from the above):

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

I'm guessing this somehow adds the references in - but I can't find the "Properties" of (I'm assuming) the namespace of the package generation class. Can anyone help here? Sounds like ProjectFile is a member of CreateTemporaryVCProject - buried deep in the framework and a little short on documentation.

I'm also concerned about the need to supply the wrapper files as discussed. Did you manage to get around this or would it still be necessary to supply these; even once you've added the XML resources I refer to above? If so I reckon I may have to take the plunge with custom components.

|||

ConsoleApplication1.Properties.Resources.ProjectFile refers to a property called ProjectFile in the application CarlaC wrote. That is basically a string resource. Look at the Resources tab in your Visual Studio Project, or have a look in the MSDN docs on this.

It is not really important, what is important is the XML that that property contained. As per the name and my description above, it is the "project file", the XML stuff a bit like what you see if you open a csproj in notepad now. The project file will hold the references, and other project level infromation. The best thing to do would be to reverse engineer a package you built in the designer. That is what I did, and to be honest I just don't think this is feasible. So I only spent a few hours on the topic, but there was an awfull lot of code generation logic embeded in the UI that you cannot access. Damn internal methods, seaaled classes etc, and decompiling code to that degree, yuk.

Personally I think this is just too much work. I would find it easier to write my own components. Forget the dynamic stuff, it is too much work, and I cannot see anyone getting eneough reuse from such effort.

|||

CarlaC,

Not sure if you got the answers you were looking for, it's been a while since you posted this message. However, I'm working on a similar scenario and have found the exact solution for creating a script task and embedding the code in it.

To make this all work...

1. Create a new package in the designer and add the script object (and associated code).

2. Right-click on the package and select "View Code"

3. Within the XML will be two "CDATA" tags, one starting with "<VisualStudioProject>" and the other starting with "' Microsoft SQL Server Integration Services Script Task".

4. Go to the project you are creating to build your script task, I have chosen to add two string variables to the resource file which are used to hold the script in both tags mentioned above (i.e. "ScriptTaskCode" and "ScriptTaskProjFile").

5. Once you have set the two properties in your resource file (or in the local code page) you can then use the following code to load the scripts into the script component:

'NOTE: You will need a reference to the following in your class:

'C:\Program Files\Microsoft SQL Server\90\DTS\Binn\Microsoft.SqlServer.VSAHosting.dll

'C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.ScriptTask.dll

'add a scripting task to the package

scriptTaskHost = TryCast(Me.m_pkg.Executables.Add("STOCKTongue TiedCRIPTTASK"), TaskHost)

scriptTaskHost.Properties("Name").SetValue(scriptTaskHost, "PkgUpdate")

scriptTaskHost.Properties("Description").SetValue(scriptTaskHost, "PkgUpdate")

'load the script task code from the resource file

scriptTask = TryCast(scriptTaskHost.InnerObject, ScriptTask)

scriptTask.SetUniqueVsaProjectName()

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/ScriptMain.vsaitem", My.Resources.ScriptTaskCode)

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/" & scriptTask.VsaProjectName & ".vsaproj", My.Resources.ScriptTaskProjFile)

scriptTask.PreCompile = False

'save everything

ssisApp = New Application()

ssisApp.SaveToDtsServer(Me.m_pkg, Nothing, "MSDB\" & Me.m_pkg.Name, serverName)

Programmatically creating Transformation Script Component

Does anyone have any examples of programmatically creating a Transformation Script Component (or Source/Destination) in the dataflow? I have been able to create other Transforms for the dataflow like Derived Column, Sort, etc. but for some reason the Script Component doesn't seem to work the same way.

I have done it as below trying many ways to get the componentClassId including the AssemblyQualifiedname & the GUID as well. No matter, what I do, when it hits the ProvideComponentProperties, it get Exception from HRESULT: 0xC0048021

IDTSComponentMetaData90 scriptPropType = dataFlow.ComponentMetaDataCollection.New();

scriptPropType.Name = "Transform Property Type";

scriptPropType.ComponentClassID = "DTSTransform.ScriptComponent";

// have also tried scriptPropType.ComponentClassID =typeof(Microsoft.SqlServer.Dts.Pipeline.ScriptComponent).AssemblyQualifiedName;

scriptPropType.Description = "Transform Property Type";

CManagedComponentWrapper instance2 = scriptPropType.Instantiate();

instance2.ProvideComponentProperties();

Any help or examples would be greatly appreciated! Thanks!

If you have not deduced, the error 0xC0048021 means that the component is not installed basically, so I'd say whatever you are using for the ComponentClassID is not right as you suspect. (http://wiki.sqlis.com/default.aspx/SQLISWiki/0xC0048021.html)

As a start point, what values have you tried., and did they include this -

Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost, Microsoft.SqlServer.TxScript, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

Is that assembly in the GAC?

|||

thanks! worked like a charm.

Now...I have the inputs selected and the outputs added but can't figure out how to add the actual script code. I don't see any custom properties that look like a script. I know I have to override the ScriptMain routines, just not sure how.

Again any help or examples would be great. thanks

|||

Can you find a SourceCode property? Looking in Books Online, it seems that MS have pretty much neglected to document the component object model, and even in the limited component property documentation (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/dtsref9/html/56f5df6a-56f6-43df-bca9-08476a3bd931.htm#script) this property is not listed. I’d say they just have not documented this at all, so is it even supported? A think it is rather pants if you cannot build packages entirely in code. Still, have a look at the SourceCode property, and perhaps have a look at what it is if you load an existing package via the object model. Another place to look is the raw XML of an existing DTSX file, but bare in mind this has been XML encoded in various unknown ways and may not be the directly assignable as you see the Xml, hence I suggested looking at an existing component through the object model.

|||

Yes, found the SourceCode custom property after last post, but am having lots of trouble figuring out what to put in there.

I am comparing the XML of the a package where the script was created through bids vs the script I'm trying to create programmatically. In Bids, It goes from an arrayElementCount of 0 with the default script to an arrayElementCount of 4 once you make change to the script. It adds an element for a .vsaproj, an element for the references, an element for .vsaitem. No clue how to add those items. I can see that the Script Task on the Control Flow does something similiar but has built in routines SetUniqueVsaProjectName & CodeProvider.PutSourceCode. So far, I'm not finding the corresponding routines for the Script Component. Any clues on that? thanks

|||

I've been doing some playing with this. The value of SourceCode is just a string array, so you can easily create a this array to set it. There are four items in the array as you note. They seem to be in pairs, a moniker and some detail. You can examine these in detail for yourself, but the monikers seem to be a standard format and, and even the project xml seems fairly sensible, then you just have the VB.Net code. So far there is nothing that could not be easily derived, even the moniker and project format just uses a Guid, albeit formatted ( Guid.ToString("n") ).

The major issue is that you also need to supply the wrapper code. Look in the project Xml (array element 1, or the second item) and you will see if references 3 files, only one of which is ScriptMain, the code we normally write. The other two are the wrappers. You can see these in the VSA designer if you look, but they are auto-generated at design-time for you.

So without these wrappers our basic code will never compile. This of course raises the issue of compilation. Normally the PreCompile property is true, so the designer compiles the code. This ends up as base 64 encoded string in another property, BinaryCode (?).

We can access the VSA compilation engine, and may even be able to get the compiled code back as binary, so we can base64 encode and set the property, but we still lack the wrappers. These seem like a lot of hard work, it seems MS generates them, but in sealed/internal design-time modules. So maybe we just write our own wrappers? Possible, but this means the package will not be maintainable via the UI. Is that an issue?

|||

Thanks for looking into it. We were on the same track. We did get the script component to work but had to set the Precompile to false. Since we are going to be running it on 64bit, that won't work for us. We need to set the property "BinaryCode" to the compiled code. Looking into ways to get the binary code. But we are also pursuing building custom components instead of script components.

String[] scriptValue = new String[4];

scriptValue[0] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @.".vsaproj";

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

scriptValue[2] = @."dts://Scripts/" + scriptPropType.CustomPropertyCollection["VsaProjectName"].Value + @."/ScriptMain.vsaitem";

scriptValue[3] = "' Microsoft SQL Server Integration Services user script component\r\n"

+ "' This is your new script component in Microsoft Visual Basic .NET \r\n"

+ "' ScriptMain is the entrypoint class for script components\r\n"

+ "\r\n"

+ "Imports System \r\n"

+ "Imports System.Data \r\n"

+ "Imports System.Math \r\n"

+ "Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper \r\n"

+ "Imports Microsoft.SqlServer.Dts.Runtime.Wrapper \r\n"

+ " \r\n"

+ "Public Class ScriptMain \r\n"

+ " Inherits UserComponent \r\n"

+ " \r\n"

+ " Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer) \r\n"

+ " ' \r\n"

+ " 'Code Here \r\n"

+ " ' \r\n"

+ " End Sub \r\n"

+ " \r\n"

+ "End Class \r\n";

IDTSDesigntimeComponent90 anIDTSDesigntimeComponent90 = instance2 as IDTSDesigntimeComponent90;

anIDTSDesigntimeComponent90.SetComponentProperty("SourceCode", scriptValue);

anIDTSDesigntimeComponent90.SetComponentProperty("PreCompile", false);

|||Yep the 64bit will be a killer for you. Whilst it is possible to genarete your own wrappers, custom components may well be easier. To be honest you could probably write your own component that accepted .Net code, easier than you can simulate the stock component. If the code is reasonably static custom components would be easier, I find them easier anyway.|||

You have done very good investigation. Could you please post full example of how you programmatically created a Transformation Script Component. I have a similar task and would appreciate your help.

|||

I'm also trying to generate a script component programmatically and this post has been very useful, just about the only info I could find on it.

I've followed through what's above and incorporated this into my own project, but I'm stuck with this bit (from the above):

scriptValue[1] = ConsoleApplication1.Properties.Resources.ProjectFile;

I'm guessing this somehow adds the references in - but I can't find the "Properties" of (I'm assuming) the namespace of the package generation class. Can anyone help here? Sounds like ProjectFile is a member of CreateTemporaryVCProject - buried deep in the framework and a little short on documentation.

I'm also concerned about the need to supply the wrapper files as discussed. Did you manage to get around this or would it still be necessary to supply these; even once you've added the XML resources I refer to above? If so I reckon I may have to take the plunge with custom components.

|||

ConsoleApplication1.Properties.Resources.ProjectFile refers to a property called ProjectFile in the application CarlaC wrote. That is basically a string resource. Look at the Resources tab in your Visual Studio Project, or have a look in the MSDN docs on this.

It is not really important, what is important is the XML that that property contained. As per the name and my description above, it is the "project file", the XML stuff a bit like what you see if you open a csproj in notepad now. The project file will hold the references, and other project level infromation. The best thing to do would be to reverse engineer a package you built in the designer. That is what I did, and to be honest I just don't think this is feasible. So I only spent a few hours on the topic, but there was an awfull lot of code generation logic embeded in the UI that you cannot access. Damn internal methods, seaaled classes etc, and decompiling code to that degree, yuk.

Personally I think this is just too much work. I would find it easier to write my own components. Forget the dynamic stuff, it is too much work, and I cannot see anyone getting eneough reuse from such effort.

|||

CarlaC,

Not sure if you got the answers you were looking for, it's been a while since you posted this message. However, I'm working on a similar scenario and have found the exact solution for creating a script task and embedding the code in it.

To make this all work...

1. Create a new package in the designer and add the script object (and associated code).

2. Right-click on the package and select "View Code"

3. Within the XML will be two "CDATA" tags, one starting with "<VisualStudioProject>" and the other starting with "' Microsoft SQL Server Integration Services Script Task".

4. Go to the project you are creating to build your script task, I have chosen to add two string variables to the resource file which are used to hold the script in both tags mentioned above (i.e. "ScriptTaskCode" and "ScriptTaskProjFile").

5. Once you have set the two properties in your resource file (or in the local code page) you can then use the following code to load the scripts into the script component:

'NOTE: You will need a reference to the following in your class:

'C:\Program Files\Microsoft SQL Server\90\DTS\Binn\Microsoft.SqlServer.VSAHosting.dll

'C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.ScriptTask.dll

'add a scripting task to the package

scriptTaskHost = TryCast(Me.m_pkg.Executables.Add("STOCKTongue TiedCRIPTTASK"), TaskHost)

scriptTaskHost.Properties("Name").SetValue(scriptTaskHost, "PkgUpdate")

scriptTaskHost.Properties("Description").SetValue(scriptTaskHost, "PkgUpdate")

'load the script task code from the resource file

scriptTask = TryCast(scriptTaskHost.InnerObject, ScriptTask)

scriptTask.SetUniqueVsaProjectName()

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/ScriptMain.vsaitem", My.Resources.ScriptTaskCode)

scriptTask.CodeProvider.PutSourceCode("dts://Scripts/" & scriptTask.VsaProjectName & "/" & scriptTask.VsaProjectName & ".vsaproj", My.Resources.ScriptTaskProjFile)

scriptTask.PreCompile = False

'save everything

ssisApp = New Application()

ssisApp.SaveToDtsServer(Me.m_pkg, Nothing, "MSDB\" & Me.m_pkg.Name, serverName)

|||Have any of you managed to create a Source Script Component programmatically. I seem to only be able to create Transformation Script Components. Thanks.
|||Hi everyone.
I got a problem with this type of programmation (i.e. programming a transform script component).

I think I did things like specified on this topic, I get no errors during the programmation, but when I open my package in design mode it says a 'NullReferenceException' on the script component ... and so I'm not able to view/modify it ...

My problem certainly comes from the source code. Here is the string array for setting the SourceCode property :

sourceCodeValue(0) = "dts://Scripts/" & "ScriptComponent_6f92b20c556448d1bfa78340623eb6d2" & _
"/" & "ScriptComponent_6f92b20c556448d1bfa78340623eb6d2" & ".vsaproj"
sourceCodeValue(1) = "<VisualStudioProject><VisualBasic Version = ""8.0.50727.791"" MVID = ""{00000000-0000-0000-0000-000000000000}"" ProjectType = ""Local"" ProductVersion = ""8.0.50727"" SchemaVersion = ""2.0"">" + _
"<Build><Settings DefaultNamespace = ""ScriptComponent_6f92b20c556448d1bfa78340623eb6d2"" OptionCompare = ""0"" OptionExplicit = ""1"" OptionStrict = ""1"" ProjectName = ""ScriptComponent_6f92b20c556448d1bfa78340623eb6d2"" ReferencePath = ""C:\WINDOWS\assembly\GAC_MSIL\Microsoft.SqlServer.TxScript\9.0.242.0__89845dcd8080cc91\;C:\WINDOWS\assembly\GAC_MSIL\Microsoft.SqlServer.PipelineHost\9.0.242.0__89845dcd8080cc91\;C:\WINDOWS\assembly\GAC_MSIL\Microsoft.SqlServer.DTSPipelineWrap\9.0.242.0__89845dcd8080cc91\;C:\WINDOWS\assembly\GAC_32\Microsoft.SqlServer.DTSRuntimeWrap\9.0.242.0__89845dcd8080cc91\"" TreatWarningsAsErrors = ""false"" WarningLevel = ""1"" RootNamespace = ""ScriptComponent_6f92b20c556448d1bfa78340623eb6d2"">" + _
"<Config Name = ""Debug"" DefineConstants = """" DefineDebug = ""true"" DefineTrace = ""true"" DebugSymbols = ""true"" RemoveIntegerChecks = ""false""/></Settings>" + _
"<References><Reference Name = ""System"" AssemblyName = ""System""/>" + _
"<Reference Name = ""System.Data"" AssemblyName = ""System.Data""/>" + _
"<Reference Name = ""Microsoft.SqlServer.TxScript"" AssemblyName = ""Microsoft.SqlServer.TxScript""/>" + _
"<Reference Name = ""Microsoft.SqlServer.PipelineHost"" AssemblyName = ""Microsoft.SqlServer.PipelineHost""/>" + _
"<Reference Name = ""Microsoft.SqlServer.DTSPipelineWrap"" AssemblyName = ""Microsoft.SqlServer.DTSPipelineWrap""/>" + _
"<Reference Name = ""Microsoft.SqlServer.DTSRuntimeWrap"" AssemblyName = ""Microsoft.SqlServer.DTSRuntimeWrap""/></References>" + _
"<Imports><Import Namespace = ""Microsoft.VisualBasic""/></Imports></Build>" + _
"<Files><Include><File RelPath = ""ScriptMain"" BuildAction = ""Compile"" ItemType = ""2""/>" + _
"</Include></Files><Folders><Include/></Folders></VisualBasic></VisualStudioProject>"
'"<File RelPath = ""BufferWrapper"" BuildAction = ""Compile"" ItemType = ""2""/>" + _
'"<File RelPath = ""ComponentWrapper"" BuildAction = ""Compile"" ItemType = ""2""/>" + _
sourceCodeValue(2) = "dts://Scripts/" & "ScriptComponent_6f92b20c556448d1bfa78340623eb6d2" & _
"/ComponentWrapper.vsaitem"
sourceCodeValue(3) = "Imports System" + _
"\nImports System.Data" + _
"\nImports Microsoft.SqlServer.Dts.Pipeline" + _
"\nImports Microsoft.SqlServer.Dts.Pipeline.Wrapper" + _
"\nImports Microsoft.SqlServer.Dts.Runtime.Wrapper" + _
"\nPublic Class UserComponent Inherits ScriptComponent" + _
"\nPublic Connections As New Connections(Me)" + _
"\nPublic Variables As New Variables(Me)" + _
"\nPublic Overrides Sub ProcessInput(ByVal InputID As Integer, ByVal Buffer As PipelineBuffer)" + _
"\nIf InputID =" + componentSyntax.InputCollection(0).ID.ToString + " Then" + _
"\nEntrée0_ProcessInput(New Entrée0Buffer(Buffer, GetColumnIndexes(InputID)))" + _
"\nEnd If" + _
"\nEnd Sub" + _
"\nPublic Overridable Sub Entrée0_ProcessInput(ByVal Buffer As Entrée0Buffer)" + _
"\nWhile Buffer.NextRow()" + _
"\nEntrée0_ProcessInputRow(Buffer)" + _
"\nEnd While" + _
"\nEnd Sub" + _
"\nPublic Overridable Sub Entrée0_ProcessInputRow(ByVal Row As Entrée0Buffer)" + _
"\nEnd Sub" + _
"\nEnd Class" + _
"\nPublic Class Connections" + _
"\nDim ParentComponent As ScriptComponent" + _
"\nPublic Sub New(ByVal Component As ScriptComponent)" + _
"\nParentComponent = Component" + _
"\nEnd Sub" + _
"\nEnd Class" + _
"\nPublic Class Variables" + _
"\nDim ParentComponent As ScriptComponent" + _
"\nPublic Sub New(ByVal Component As ScriptComponent)" + _
"\nParentComponent = Component" + _
"\nEnd Sub" + _
"\nEnd Class"
sourceCodeValue(4) = "dts://Scripts/" & "ScriptComponent_6f92b20c556448d1bfa78340623eb6d2" & _
"/BufferWrapper.vsaitem"
sourceCodeValue(5) = "Imports System" + _
"\nImports System.Data" + _
"\nImports Microsoft.SqlServer.Dts.Pipeline" + _
"\nImports Microsoft.SqlServer.Dts.Pipeline.Wrapper" + _
"\nPublic Class Entrée0Buffer Inherits ScriptBuffer" + _
"\nPublic Sub New(ByVal Buffer As PipelineBuffer, ByVal BufferColumnIndexes As Integer())" + _
"\nMyBase.New(Buffer, BufferColumnIndexes)" + _
"\nEnd Sub"
For Each field As String In fieldArray
sourceCodeValue(5) = sourceCodeValue(5) + _
"\nPublic ReadOnly Property [" + field.ToString() + "]() As String" + _
"\nGet" + _
"\nReturn CType(Me(" + fieldArray.IndexOf(field).ToString + "), String)" + _
"\nEnd Get" + _
"\nEnd Property" + _
"\nPublic ReadOnly Property [" + field.ToString().ToString + "_IsNull] As Boolean" + _
"\nGet" + _
"\nReturn IsNull(" + fieldArray.IndexOf(field).ToString + ")" + _
"\nEnd Get" + _
"\nEnd Property"
Next
sourceCodeValue(5) = sourceCodeValue(5) + _
"\nPublic Sub DirectRowToisValid()" + _
"\nMyBase.DirectRow(" + componentSyntax.OutputCollection(0).ID.ToString + ")" + _
"\nEnd Sub" + _
"\nPublic Function NextRow() As Boolean" + _
"\nNextRow = MyBase.NextRow()" + _
"\nEnd Function" + _
"\nPublic Function EndOfRowset() As Boolean" + _
"\nEndOfRowset = MyBase.EndofRowset" + _
"\nEnd Function" + _
"\nEnd Class"
sourceCodeValue(6) = "dts://Scripts/" & "ScriptComponent_6f92b20c556448d1bfa78340623eb6d2" & _
"/ScriptMain.vsaitem"
sourceCodeValue(7) = "' Microsoft SQL Server Integration Services user script component" + _
"\n' This is your new script component in Microsoft Visual Basic .NET" + _
"\n' ScriptMain is the entrypoint class for script components" + _
"\nImports System" + _
"\nImports System.Data" + _
"\nImports Microsoft.SqlServer.Dts.Pipeline.Wrapper" + _
"\nImports Microsoft.SqlServer.Dts.Runtime.Wrapper" + _
"\nPublic Class ScriptMain Inherits UserComponent" + _
"\nEnd Class"|||Sorry I submited my post too fast.

Thanks to all of you for any kind of help.

Bobby

P.S.: Don't look at my english ;) I'm french and did my best :)

Programmatically creating SSIS package

Hi guys,

I was intended to write a program that will create a SSIS package which will import data from a CSV file to the SQL server 2005. But I did not find any good example for this into the internet. I found some example which exports data from SQL server 2005 to CSV files. And following those examples I have tried to write my own. But I am facing some problem with that. What I am doing here is creating two connection manager objects, one for Flat file and another for OLEDB. And create a data flow task that has two data flow component, one for reading source and another for writing to destination. While debugging I can see that after invoking the ReinitializedMetaData() for the flat file source data flow component, there is not output column found. Why it is not fetching the output columns from the CSV file? And after that when it invokes the ReinitializedMetaData() for the destination data flow component it simply throws exception.

Can any body help me to get around this problem? Even can anyone give me any link where I can find some useful article to accomplish this goal?

I am giving my code here too.

I will appreciate any kind of suggestion on this.

Code snippet:

public void CreatePackage()

{

string executeSqlTask = typeof(ExecuteSQLTask).AssemblyQualifiedName;

Package pkg = new Package();

pkg.PackageType = DTSPackageType.DTSDesigner90;

ConnectionManager oledbConnectionManager = CreateOLEDBConnection(pkg);

ConnectionManager flatfileConnectionManager =

CreateFileConnection(pkg);

// creating the SQL Task for table creation

Executable sqlTaskExecutable = pkg.Executables.Add(executeSqlTask);

ExecuteSQLTask execSqlTask = (sqlTaskExecutable as Microsoft.SqlServer.Dts.Runtime.TaskHost).InnerObject as ExecuteSQLTask;

execSqlTask.Connection = oledbConnectionManager.Name;

execSqlTask.SqlStatementSource =

"CREATE TABLE [MYDATABASE].[dbo].[MYTABLE] \n ([NAME] NVARCHAR(50),[AGE] NVARCHAR(50),[GENDER] NVARCHAR(50)) \nGO";

// creating the Data flow task

Executable dataFlowExecutable = pkg.Executables.Add("DTS.Pipeline.1");

TaskHost pipeLineTaskHost = (TaskHost)dataFlowExecutable;

MainPipe dataFlowTask = (MainPipe)pipeLineTaskHost.InnerObject;

// Put a precedence constraint between the tasks.

PrecedenceConstraint pcTasks = pkg.PrecedenceConstraints.Add(sqlTaskExecutable, dataFlowExecutable);

pcTasks.Value = DTSExecResult.Success;

pcTasks.EvalOp = DTSPrecedenceEvalOp.Constraint;

// Now adding the data flow components

IDTSComponentMetaData90 sourceDataFlowComponent = dataFlowTask.ComponentMetaDataCollection.New();

sourceDataFlowComponent.Name = "Source Data from Flat file";

// Here is the component class id for flat file source data

sourceDataFlowComponent.ComponentClassID = "{90C7770B-DE7C-435E-880E-E718C92C0573}";

CManagedComponentWrapper managedInstance = sourceDataFlowComponent.Instantiate();

managedInstance.ProvideComponentProperties();

sourceDataFlowComponent.

RuntimeConnectionCollection[0].ConnectionManagerID = flatfileConnectionManager.ID;

sourceDataFlowComponent.

RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.ToConnectionManager90(flatfileConnectionManager);

managedInstance.AcquireConnections(null);

managedInstance.ReinitializeMetaData();

managedInstance.ReleaseConnections();

// Get the destination's default input and virtual input.

IDTSOutput90 output = sourceDataFlowComponent.OutputCollection[0];

// Here I dont find any columns at all..why?

// Now adding the data flow components

IDTSComponentMetaData90 destinationDataFlowComponent = dataFlowTask.ComponentMetaDataCollection.New();

destinationDataFlowComponent.Name =

"Destination Oledb compoenent";

// Here is the component class id for Oledvb data

destinationDataFlowComponent.ComponentClassID = "{E2568105-9550-4F71-A638-B7FE42E66922}";

CManagedComponentWrapper managedOleInstance = destinationDataFlowComponent.Instantiate();

managedOleInstance.ProvideComponentProperties();

destinationDataFlowComponent.

RuntimeConnectionCollection[0].ConnectionManagerID = oledbConnectionManager.ID;

destinationDataFlowComponent.

RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.ToConnectionManager90(oledbConnectionManager);

// Set the custom properties.

managedOleInstance.SetComponentProperty("AccessMode", 2);

managedOleInstance.SetComponentProperty("OpenRowset", "[MYDATABASE].[dbo].[MYTABLE]");

managedOleInstance.AcquireConnections(null);

managedOleInstance.ReinitializeMetaData(); // Throws exception

managedOleInstance.ReleaseConnections();

// Create the path.

IDTSPath90 path = dataFlowTask.PathCollection.New(); path.AttachPathAndPropagateNotifications(sourceDataFlowComponent.OutputCollection[0],

destinationDataFlowComponent.InputCollection[0]);

// Get the destination's default input and virtual input.

IDTSInput90 input = destinationDataFlowComponent.InputCollection[0];

IDTSVirtualInput90 vInput = input.GetVirtualInput();

// Iterate through the virtual input column collection.

foreach (IDTSVirtualInputColumn90 vColumn in vInput.VirtualInputColumnCollection)

{

managedOleInstance.SetUsageType(

input.ID, vInput, vColumn.LineageID, DTSUsageType.UT_READONLY);

}

DTSExecResult res = pkg.Execute();

}

public ConnectionManager CreateOLEDBConnection(Package p)

{

ConnectionManager ConMgr;

ConMgr = p.Connections.Add("OLEDB");

ConMgr.ConnectionString =

"Data Source=VSTS;Initial Catalog=MYDATABASE;Provider=SQLNCLI;Integrated Security=SSPI;Auto Translate=false;";

ConMgr.Name = "SSIS Connection Manager for Oledb";

ConMgr.Description = "OLE DB connection to the Test database.";

return ConMgr;

}

public ConnectionManager CreateFileConnection(Package p)

{

ConnectionManager connMgr;

connMgr = p.Connections.Add("FLATFILE");

connMgr.ConnectionString = @."D:\MyCSVFile.csv";

connMgr.Name = "SSIS Connection Manager for Files";

connMgr.Description = "Flat File connection";

connMgr.Properties["Format"].SetValue(connMgr, "Delimited");

connMgr.Properties["HeaderRowDelimiter"].SetValue(connMgr, Environment.NewLine);

return connMgr;

}

And my CSV files is as follows

NAME, AGE, GENDER

Jon,52,MALE

Linda, 26, FEMALE

Thats all. Thanks.

As mentioned earlier, this CSV to OLEDB package generator is not far from working.

First, the AccessMode on the OLEDB destination is set to the constant 2, which the "Sql Command" constant. Change that back to 0 ("Table or View").

FYI, the OLEDB destination's Access Mode enumeration is undocumented, but nevertheless can be found in the following dll: Microsoft SQL Server\DTS\PipelineComponents\OleDbDest.dll using a program like "PE Explorer".

Enum AccessMode;

AM_OPENROWSET = 0
AM_OPENROWSET_VARIABLE = 1
AM_SQLCOMMAND = 2
AM_OPENROWSET_FASTLOAD = 3
AM_OPENROWSET_FASTLOAD_VARIABLE = 4

Next, the target table doesn't exist , yet ReinitializeMetadata() for the OLEDB destination component will by default attempt to retrieve the target table's meta data. The table isn't there, so an exception is thrown. Therefore, as part of the driving program, you may wish to create the table temporarily (this table create is separate from the create in the Execute SQL Task), so that there is meta-data to reinitialize.

That should eliminate exceptions, but it doesn't mean the package will validate or execute successfully, just that you could save it to xml.

Then, add source columns for your flat file. SSIS does not materialize them for you (at least as far as I know), so the user needs to do perform that programmatically.|||

Hello jaegd,

At last I made it work today . Your tips tremendously helped me. After implementing your suggestions I had to do very little coding to make it working. Thanks a lot .

Anyway, as I am creating the source columns programmatically for the Flat file connection, I had to read the columns from the CSV file using .net IO functionality. Is there any way to accomplish this through SSIS APIs?

Thank you very much again.

Regards

Moim

|||

Hello,

How did you create the metadata for the destination?

Thanks in advance.

Cheers,

kix