How to execute SqlCommand using OLEDB connection in SSIS script component - sql-server

I am using SSIS 2019 and am able to execute SQL Command with ADO.Net Connection Manager.
I want to use OLEDB connection manager in a Script component within a Data Flow Task and I am getting the below error:
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.
Can someone please let me know if we can use OLEDB Connection in SSIS script component in a Data flow.
Here is code for connection strings
public override void PreExecute()
{
string conn = this.Connections.Connection.ConnectionString;
}
I am not getting build error in script C# code. But getting error at script component.

Using a Script Component
To access a connection manager within a script component, you should first specify this connection manager from the script component editor as shown in the image below:
Then, within the script component, you should use the Connections variable to access this connection manager (In this example, the connection manager assigned name is Connection):
var constr = Connections.Connection.ConnectionString;
screenshot
Executing a SQL command using C#
Next, you should use this connection string to initiate a SqlConnection object in order to use it by a SqlCommand as follows:
using(SqlConnection conn = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("Write here your SQL command", conn))
{
conn.Open();
cmd.ExecuteNonQuery();
}
}
Make sure you added a reference for using System.Data.SqlClient to use the SqlConnection and SqlCommand objects.
Important Note: If you are using SQL authentication, you should re-add the password to the connection string since it will not be retrieved from the connection manager for security reasons.
Using a Script Task
You should first retrieve the OLE DB connection string from the connection manager using the following command:
string constr = Dts.Connections["OledbCM"].ConnectionString;
Demonstration
I added Messagebox.Show(constr) command to the script task to show how the connection string looks like once retrieved:
Helpful Links:
SSIS Script Task : ConnectionString for ADO.Net & OleDb ConnectionManager
Check OLDEDB database Connection using script task in SSIS
Update 1: SqlConnection vs. OleDbConnection
Since you are using SqlConnection class which represents a connection to a SQL Server database. You will encounter the following error while trying to use the connection string retrieved from an OleDb Connection:
Keyword not supported "Provider"
The main reason is that the OleDB connection requires that the connection string contains the provider information since it has the ability to connect to different providers such as Oracle, Excel, Access, SQL. While SqlConnection class does not support this information since it is only using the SQL Server Native client provider.
How to solve this issue?
You can simply use a System.Data.OleDb.OleDbConnectionStringBuilder object to remove this part using the following code:
string con = Dts.Connections["OledbCM"].ConnectionString;
var connBldr = new OleDbConnectionStringBuilder(con);
connBldr.Remove("Provider");
con = connBldr.ConnectionString;
Or you can use Linq: (Remember to add the System.Linq namespace)
string con = Dts.Connections["OledbCM"].ConnectionString;
con = string.Join(";", con.Split(';').Where(c =>
!c.TrimStart().StartsWith("Provider")));
References
How do I remove "Provider=..." from a connection string

Related

Error when opening ADODB recordset using odbc dsn in MS Access

I have a MS Access application that has been in use for at least 10 years. Recently I moved my work to a new development machine with Office 365 and SQL Server Express 2019 installed. The machine OS is Windows 10 Pro. In my old machine my application would run just fine. There is a query using a stored procedure that retrieves a piece of data from a table in the SQL Server backend. I call this procedure using a ADODB recordset based on the stored procedure output. All my calls use a connection string based on an ODBC DNS. This connection string works fine on the new machine when relinking tables to the SQL Server backend, but when I use it in the ADODB connection I get an error "[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified". On the old Windows 7 development machine this ran fine. It also runs on the client's machines which are Windows 10 and Office 365. The code that raises the error follows. The error occurs at the open connection line. The connection string is: ODBC;DSN=VROM;Trusted_Connection=Yes;APP=2019 Microsoft Office system;DATABASE=VROM1.
Set con = New ADODB.Connection
con.ConnectionString = DLookup("Link", "tblLinkData", "Use = True")
con.Open
Set rs = New ADODB.Recordset
My question "Is there a setting in SQL Server that could be causing this error?". As far as I can tell both systems are set up the same, but there is obviously something different between the two. Is there another reason this could be working on one system and not another?
Hum, where to start?
Ok, first up, if you using the ODBC panel to create a ODBC connection, then you NEVER were actually using a ADO connection in that DSN config = ODBC!!!!
That means you been feeing ADO a ODBC connection string. you can do this, but at least lets be aware of what is going on.
Next up:
Are you running the SQL browser service? You MUST do that now!. Don't know if you installed a later version of SQL SERVER, but a few versions ago you will find now that you MUST run the browser service.
This one:
The reason of course is that you can (may) have multiple instances of sql server running, and the default instance (SQLEXPRESS) now MUST BE specified. As noted older instances did NOT have this requirement. And to "resolve" the multiple instances, you now must run the SQL browser service. As noted, this was NOT a requirement in the past - it is now. That browser service is what connects the IP/server name to the instance, and you now in most cases have to run this.
There are exceptions, but you don't want much pain.
Next up:
For a VERY long time, it is recommended for Access linked tables you use a DSN-less connection. that way then at deployment time to all workstations, you don't need to setup a DSN on each workstation.
And if you link Access tables using a FILE dsn (not system or user), then upon the table link process, access BY DEFAULT converts all table links to DSN-less. That means once you linked, then you could even delete the DSN - you do NOT need it anymore.
Again: this ONLY holds true if and when you create a FILE dsn, and use that to link the tables. So, that takes care of the DSN-less linked tables.
Note that if you were to modify the DSN, you would have to link, since I just told you by default access creates + uses dsn-less links (assuming you used a FILE dsn to link).
now, you CAN of course use that SAME dsn for ADO, but that means you are feeding ADO a ODBC driver connection!!!
If you want to create a real ADO connection, then you would/could/should say use this:
Dim strCon As String
strCon = "Provider=SQLOLEDB;;Initial Catalog=TEST4; " & _
"Data Source =.\SQLEXPRESS;Trusted_Connection=yes"
Dim conn As New ADODB.Connection
conn.ConnectionString = strCon
conn.Open
Dim rst As New ADODB.Recordset
rst.Open "SELECT * from tblHotels", conn
Do While rst.EOF = False
Debug.Print rst!HotelName
rst.MoveNext
Loop
Now now how I used a "." for localhost. That could be replaced with (local), or in fact the computer (server) name say like this:
strCon = "Provider=SQLOLEDB;;Initial Catalog=TEST4; " & _
"Data Source =ALBERTKALLAL-PC\SQLEXPRESS;Trusted_Connection=yes"
Next up, make sure you enabled the TC/IP connections.
here:
However, since your case all along you actually been using ODBC driver with ADO, then I would not rock the boat.
But, check your settings as per above.
Since linked tables, and quite much everything else is DAO + odbc?
then I would probably not introduce ADO into that application for JUST calling + using sql server store procedures.
I as a general rule would say use this;
with currentdb.tabledefs("qryPT")
.sql = "exec MyProcName"
.execute
end with
Or, if it is to return data, then I would use this:
dim rst as DAO.RecordSet
with currentdb.tabledefs("qryPT")
.sql = "exec MyProcName"
set rst = .OpenRecordSet()
end with
So, I am hard pressed to find a reason to use ADO. Now of course since you been using ADO, then I guess I would continue to do so.
but, check the browser settings. And if the tables were linked using a FILE dsn, then they are dsn-less.
You could try feeding the ADO connection a existing connection from a existing linked table.
eg:
strCon = CurrentDb.TableDefs("dbo_tblHotels").Connect
strCon = Mid(strCon, 6)
Dim conn As New ADODB.Connection
conn.ConnectionString = strCon
conn.Open
Skipping the first 6 chars skips this part:
ODBC;DRIVER=SQL Server;SERVER=ALBERTKALLAL-PC\SQLEXPRESS;
UID=AlbertKallal;Trusted_Connection=Yes;APP=Microsoft Office 2010;
DATABASE=Test4;Network=DBMSLPCNM
So once again we are feeding ADO ODBC connection string.
(of course above connection string is one line).

SSIS: Configuration of Dynamic Connection String Integrated Security Mode

Setup
In the local environments, we're using SQL Authentication with Username and Password to connect to the databases. I created a Project Connection Manager that has expressions bound to Project Properties, Username and Password being set to sensitive.
On the dev server, when the SSIS run, it needs to use an AD account. I might need to create a Credential/Proxy for the SQL Agent, but for now I'm logged in as the user and I execute the packag through SQL.
Problem
In the SSIS project itself, I'm trying to configure a dynamic connection string to use Integrated Security in one case, and SQL Account in another. I just can't figure out how to do it. Things I tried:
1- Created a boolean "UseIntegratedSecurity" parameter. In the connection string, use that bool to set IntegratedSecurity=SSPI or not with the expression, and also use expressions to set the other attributes of the connection string individually. It didn't work, said the connection string could not be built.
2- Created a boolean "UseIntegratedSecurity" parameter, and write my connection string as something (ugly) like: #[$Project::IntegratedSecurity] ? "Data Source="+#[$Project::SqlServerName]+";Initial Catalog="+#[$Project::SqlServerDatabase]+";Provider=SQLNCLI11.1;Auto Translate=False;Integrated Security=SSPI;" : "Data Source="+#[$Project::SqlServerName]+";Initial Catalog="+#[$Project::SqlServerDatabase]+";Provider=SQLNCLI11.1;Auto Translate=False;User ID="+#[$Project::SqlServerUsername]+";Password=" + #[$Project::SqlServerPassword]
It didn't work because since SqlServerUserName and SqlServerPassword are sensitive, it refuses.
3- Tried having Project Parameters for ConnectionString, Server, Database, User, Password and setting them all. Works locally, but on the server, I get "Invalid Authorization Specifications".
Ideas?
Thanks
You need to handle situation when in one environment you have to use SQL Authentication, and on the other - AD Authentication.
This can be done with help of SSIS Catalog Environment variables. When you create a Project file, Visual Studio automatically creates the following so called project connection parameters for each OLEDB connection manager :
CM.< conn manager name >.ConnectionString
CM.< conn manager name >.InitialCatalog
CM.< conn manager name >.Password Created as sensitive param
CM.< conn manager name >.ServerName
CM.< conn manager name >.UserName
OLEDB is an example, SSIS creates similar parameters for other connection manager types.
Important fact, you do not have to create additional project parameters. The parameters mentioned are created on project being built and are present on all projects.
We create environment variables which specify connection string, DB name (initial catalog), Server Name etc. Good thing - Connection string variable is applied first, and then amended with the other variables.
More details on these parameters is in MS Docs.
In case similar to yours, in Dev environment - using SQL Auth define Conn string for SQL Auth and specify username and password in corresponding variables. In QA env where SSPI is used - the Connection string is reworked for SSPI, UserName and Password environment variables are empty.

SSIS Connection Manager Does Not Exist

I have created a database through a task script in SSIS. When I later try to connect to that database through the Connection Manager I am told that the Connection Manager does not exist. The database is there in the server.
How can I establish the connection to the database to load the data after I've created a new DB in the script?
Error: The connection "Data Source=..;Initial Catalog=8888888;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;" is not found. This error is thrown by Connections collection when the specific connection element is not found.
From the Microsoft Forums The connection "" is not found from..
Similar question: SSIS Connection not found in package
You will need a ConnectionManager. It's an object in your project (assuming you are working in a project...) which you can add. This ConnectionManager can then be modified in order to not use a static connectionstring but to use a variable instead. This string variable as you already mentioned has then to be populated with the correct string. This can be done within your script task

C# Generic methods for database driver access in ADO.NET

I have to write a small C# program which will handle at least three differents database vendors (Oracle, Sybase ASE, SqlServer) in a dynamic way. (It will rely on customer choices to choose the database)
I decided to use "pure" managed drivers through ado.net data providers.
But, when I just try connecting, I expected code a la "One line to rule them all", just like JDBC does with :
DriverManager.getConnection(connection_string);
Instead of this, surprised, I have to write for each driver its specific code :
SqlConnection() for SqlServer
AseConnection() for Sybase
OracleConnection(), etc.
Of course, I should encapsulate -by myself- all of this inside abstract methods and dynamic loadings, but I'm wondering why such a thing doesn't already exist in .net
Mmhhh, I've got the feeling that I'm missing something
Since you have the .Net Provider for he respective database installed on the machine, you can use the DbProviderFactory, for sample:
include
using System.Data.Common;
and try something like this:
// create the provider factory from the namespace provider
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
// you could create any other provider factory.. for Oracle, MySql, etc...
// use the factory object to create Data access objects.
DbConnection connection = factory.CreateConnection(); // will return the connection object, in this case, SqlConnection ...
connection.ConnectionString = "read connection string from somewhere.. .config file for sample";
try
{
// open connection
connection.Open();
// create command to execute queries...
DbCommand command = connection.CreateCommand(); // create a SqlCommand, OracleCommand etc... depende of the provider factory configured.
// some logic
}
catch
{
}
finally
{
// close connection
connection.Close();
}
To know, what providers your application can find, you can use the DbProviderFactories.GetFactoryClasses() method to get a DataTable with details of every provider installed on the machine.

making a client server application of sales inventory system including sql database in c#

i am a beginer and i am making a client server application in c# using sql database.
i am using just two computers, at one computer i want to store my database as well as the application will also run on the same computer it one computer is the server and the client both and the another computer will be a simple client that will access the database.
can any one help me how shoud i write the code for both systems to connect the database.
thank you.
To connect to SQL Server from C#.NET, you need to create a connection string such as below:
private SqlConnection connection;
private string connectionString =
#"Server=(local);Database=Embedding_SQL_Test;User ID=sa;Password=123";
connection = new SqlConnection( connectionString );
Next, you use the SqlConnection object created above to create a 'SqlCommand', as shown below:
SqlCommand cmd = new SqlCommand( "select * from Customer where CustomerID = #Cid", connection);
The SQL query shown here can be replaced by a SELECT, INSERT, UPDATE queries etc.
Next to execute the SQL queries in the database, you use the following methods:
ExecuteReader - to execute SELECT queries
ExecuteNonQuery - to execute INSERT, DELETE, UPDATE, and SET statements.
This is a very short description of how to connect to SQL Server database from C# and execute SQL queries in the database.
For details about the connection string, the methods and their parameters check the following link: ( http://www.shahriarnk.com/Shahriar-N-K-Research-Embedding-SQL-in-C-Sharp-Java.html )
Here you will also find details about how to pass parameters to the SQL queries as well as calling stored procedures and much more.

Resources