SSIS script task can't read project variable - ssis

In my project.params I have variables such as LampUserName of type string. In my
script task I'm then trying to read them like so:
foreach (var name in new string[] { "ServerName", "InitialCatalog", "UserName", "Password" }) {
if (!Dts.Variables.Contains(string.Format("$Project::Lamp{0}", name))) {
writer.WriteLine(name);
}
}
string server_name = (string)Dts.Variables["$Project::LampServerName"].Value;
string database = (string)Dts.Variables["$Project::LampInitialCatalog"].Value;
string username = (string)Dts.Variables["$Project::LampUserName"].Value;
string password = (string)Dts.Variables["$Project::LampPassword"].Value;
Every one of those prints out that it doesn't exist and then an exception is thrown. What am I doing wrong?

Are you referencing your project parameters from a Script Component within a Data Flow Task? If so, this differs from using a Script Task within the Control Flow. After adding the project parameter in the ReadOnlyVaraiables field, it is accessible as a property of the Variable object.
string database = Variables.DatabaseParameter.ToString();

Related

Why are my promoted variables are not shared between Workshop modules in Carbon?

I have a carbon workspace with two workshop modules. One of them includes a button that opens another workshop module and should pass a promoted variable (an array) to the new module.
But when the second module is opened via the button it looks like the variable was never passed along.
In the network tab it should show an error like the below:
foundry.objects.workshop.app.workshopModuleParameters: Tried passing a list parameter when opening another Workshop module in Carbon, but list parameters are not currently supported by Carbon, so ignoring the parameter value
In that case there are two options, one is to move to non-array variables if possible:
The other one is to use a function that would take the array, convert it into a string with a specific delimiter and pass this string variable to the new module:
#Function()
public makeString(arrayToConvert: string[]): string{
var convertedString = arrayToConvert[0];
if(arrayToConvert.length===1){
return convertedString
}
for (let i =1; i<arrayToConvert.length; i++){
convertedString = convertedString.concat(",", arrayToConvert[i])
}
return convertedString;
}
Convert the array to a string with a variable:
And pass the string variable to the new module:
In the second module the string would be converted back into an array.
#Function()
public makeArray(stringToConvert: string): string[]{
var convertedArray = stringToConvert.split(",");
return convertedArray;
}

Execute stored procedure in mvc through EnterpriseLibrary

I am tyring to develop a sample project in mvc. In this, i tried to get the userlist from database (mysql). i am using enterprise library dll to set the database connectivity.
public IEnumerable<UserViewModel> GetUserList()
{
DatabaseProviderFactory factory = new DatabaseProviderFactory();
Database db = factory.Create("MySqlConnection");
DbCommand dbc = db.GetStoredProcCommand("uspGetUserList");
dbc.CommandType = CommandType.StoredProcedure;
return db.ExecuteDataSet(dbc);
}
i know the executedataset is to execute only dataset type... i want the command that execute IEnumerable type.....
thank you
If you want to return an IEnumerable type without manually constructing it (either from a DataSet or an IDataReader) then you can use accessors.
In your case your could would look like this:
public IEnumerable<UserViewModel> GetUserList()
{
DatabaseProviderFactory factory = new DatabaseProviderFactory();
Database db = factory.Create("MySqlConnection");
IEnumerable<UserViewModel> results = db.ExecuteSprocAccessor<UserViewModel>("uspGetUserList");
return results;
}
This assumes that the UserViewModel can be mapped from the stored procedure result set (e.g. column names are the same name as the property names). If not, then you would need to create a custom mapper. See Retrieving Data as Objects from the Developer's Guide for more information about accessors.

How to display variable in ssis script task

I have a 'Execute SQL task' which product a row count. see screen 1.
I am trying to print 'ContactRowCount' in ssis 'Script task'. See screen 2.
But Dts.Variables["User::ContactRowCount"] is null. I can retrieve it.
Anyone knows how to retrieve variable value from 'Execute SQL task' in script task
Screen - 1
Screen - 2
Do read documentation, all of this has been covered.
Variables
I have two variables. One is for my SQL, called Quqery, which is optional. The other is an Int32 called RowCount.
Execute SQL Task
I have an Execute SQL task that uses an OLE DB Connection Manager. I have specified that it as a ResultSet of Single Row. I use my Query variable as the source.
The value is
SELECT COUNT(1) AS ContactRowCount FROM sys.columns AS SC;
In the Result Set tab, I map the 0 ResultSet to my variable User::RowCount.
If you are using a different Connection Manager provider (ADO.NET or ODBC), then these semantics all change. But it's documented.
Script Task
I ensure that I am passing in my variable as a read only object
Within my script, I need to access that variable. This is case sensitive. Furthermore, I want the .Value property. Your code, were it to work, would be casting the SSIS Variable to a string. This results in the default of the object emitting its name Microsoft.SqlServer.Dts.Runtime.Variable
Instead, we will want to access the .Value property which is returned as an object. If you were trying to do something mathematical with this value, then you'd need to convert it to an integer value but since we're going to string, that's easy.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_454527867e9d448aad6a7f03563175b2.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
string strMessage = Dts.Variables["User::RowCount"].Value.ToString();
MessageBox.Show(strMessage);
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
use variable name in the script task and not the result set name.
Just check the variable values during runtime debug.

Using MySQL with visual studio and changing the connection at runtime

I use something like this for my application
MySqlConnection cnn = new MySqlConnection("Server=myServerAddress;" +
"Database=myDataBase;" +
"Uid=myUsername;" +
"Pwd=myPassword;");
And this changes everytime because we deploy databases with our application.
It works fine. I type in using(new connection(cnn)){ query... } and go.
And I've got it working with a dataset using a connection defined in the windows ODBC datasouce administrator.
But I'm curious, is there a way to use visual studio's dataset items using the my local test db and then change the connection of the dataset at runtime? Even better, can I use c# to programmatically add the ODBC data source at runtime?
Usually a connection string is loaded from the application exe.config file present in the same folder of the application. This connection string could be defined using the Settings tab in the project properties.
Right click on Properties of your project
Select the Settings tab (confirm the creation if you have no
settings)
Click on the ComboBox in the column type and select Connection String
Give a symbolic name to your connection
Type the connection string in the Value column (Examples at
connectionstrings.com)
Now in your project files you should have the file app.config (that becomes yourapp.exe.config) where there is a section like this
<configuration>
<connectionStrings>
<add name="MyAppConnection"
connectionString="Server=myServerAddress;Database=myDB;Uid=user;Pwd=pass;" />
</connectionStrings>
</configuration
At this point you read it in the program using
string conString = ConfigurationManager
.ConnectionStrings["MyAppConnection"]
.ConnectionString;
Instead in a dynamic situation where you want to build yourself the connection string during runtime (from user inputs, your own configuration files and so on) then you could leverage the functionality of the class MySqlConnectionStringBuilder
MySqlConnectionStringBuilder msb = new MySqlConnectionStringBuilder();
msb.Server = "localhost";
msb.Port = 3306;
msb.UserID = "root";
msb.Password = "xxx";
msb.Database = "test";
MySqlConnection cnn = new MySqlConnection(msb.ConnectionString);
cnn.Open();
Of course, these literal values could be substituted by your own variables.
The documentation of this class is surprising difficult to find. The best docs are the one of the Sql Server equivalent. It is interesting that you could read a static connection string from your config file and then change only the property needed.
string conString = ConfigurationManager
.ConnectionStrings["MyAppConnection"]
.ConnectionString;
MySqlConnectionStringBuilder msb = new MySqlConnectionStringBuilder(conString);
msb.Database = "AnotherDB";
MySqlConnection cnn = new MySqlConnection(msb.ConnectionString);
Application connection string cannot be changed at runtime.
User settings can be changed.
Assuming you are using an application setting-property named "MyConnectionString" which holds the connection string for the entire application.
On your main Program class create a global string:
internal static string Prconnstring;
Create and save this settings.cs file:
namespace MYSOLUTIONORPROJECTNAME.Properties
{
// (Not sure where I found this solution some time ago)
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
internal sealed partial class Settings
{
public Settings()
{
// // To add event handlers for saving and changing settings, uncomment the lines below:
//
// this.SettingChanging += this.SettingChangingEventHandler;
//
// this.SettingsSaving += this.SettingsSavingEventHandler;
//
}
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e)
{
// Add code to handle the SettingChangingEvent event here.
}
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e)
{
// Add code to handle the SettingsSaving event here.
}
public override object this[string propertyName]
{
get
{
if (propertyName == "MyConnectionString")
{
return Program.Prconnstring;
}
else
{
return base[propertyName];
}
}
set
{
base[propertyName] = value;
}
}
}
}
Before calling-opening any object that uses the connection string (examples include Forms that use datasets or other classes that use datasets created on the development enviroment) create your new connection string by any means you think. (Example: You might want to use as user name in the connection string the current user. Create the connection string using the info provided form the environment.)
Program.Prconnstring = thenewruntimeconnectionstring.
Now whenever the application tries to get MyConnectionString (which is hardcoded in the myapplicationname.config and cannot be changed) instead gets the new thenewruntimeconnectionstring you provided to Program.Prconnstring.
Be aware that the development connection string will be available-visible to final user, since it is just a text file. If you do not want this, you can change that file (will be a file named NAMEOFMYAPPLICATION.exe.config) during deployment, since the connection string hardcoded there, will be of no use for the running app. Do not delete it, just change.
Your connection string will be stored in your App.config (or c# equivalent). Say it's called MyConnectionString. Just add My.Settings("MyConnectionString")="[your new connection string]" to your entry point to change to database binding at runtime. E.g:
Public Sub New()
' This call is required by the designer.
InitializeComponent()
My.Settings("MyConnectionString") = "server=remotedb.uk;user id=MainUser;password=2jdi38edhnche73g;database=mainDb;persistsecurityinfo=True;allowuservariables=True;defaultcommandtimeout=480;characterset=utf8mb4"
End Sub

SSIS Script Component connection

I've been searching for a solution for days now and I still cant seem to find one. I have a problem acquiring a connection in my Script component. I need to query my database to retrieve an Id to be used before I insert it in the
public override void AcquireConnections(object Transaction)
{
connMgr = base.Connections.Connection;
conn = (SqlConnection)connMgr.AcquireConnection(null);
}
I get an exception here.
System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to class type 'System.Data.SqlClient.SqlConnection'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Any solutions?
For those that want to be able to do this in a Script Component:
Double Click the Script component to open the "Script Transformation Editor"
Click the "Connection Managers" list item.
Add a new Connection Manager. Select an existing ADO.NET connection manager.
Click on the "Script" list item and then the "Edit Script..." button.
You can do something like this inside your script:
using (SqlConnection connection = this.Connections.Connection.AcquireConnection(null) as SqlConnection)
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT [Value] FROM dbo.MyTable";
command.CommandType = CommandType.Text;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
ProfanityWords.Add(reader.GetValue(0).ToString());
}
}
}
this.Connections.Connection.ReleaseConnection(connection);
}
ADO.NET connection manger should be created and refer into the code to type cast to the SqlConnection. If you dont have the ADO.NET connection in your SSIS pakcage you will get the TypeCast exception. Following steps should be used if you want to use the SqlConnection.
Create the ADO.NET connection.
Use the following line in your code.
var connObj = Dts.Connections["ADO.NETConnectionName"].AcquireConnection(null);
var sqlConn = (SqlConnection)connObj;
Once you done with your SQL connection. Use the following code to Close/ Release your connection.
Dts.Connections["ADO.NETConnectionName"].ReleaseConnection(connObj);
Hope this helps.