SSIS Script task AcquireConnection returns Null - c#

In SSIS I have a connection defined with the following connection string:
Data Source=myserver;Initial Catalog=Spears;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;
i am attempting to use this connection from a script task:
ConnectionManager connectionManager = this.Dts.Connections["Spears"];
object acquireConnection = connectionManager.AcquireConnection(this.Dts.Transaction);
SqlConnection con = acquireConnection as SqlConnection;
con.Open();
On execution
connectionManager comes back as a fully populated ConnectionManager
object
acquireConnection is a System._ComObject
con is null
obviously opening con fails
Casting as OleDbConnection or OdbcConnection returns null as well.
What am I doing wrong ?

This problem occurs because you are using an OLEDB connection in the SSIS package instead of an ADO.NET one.
Once you change that, the code should work fine, even if Dts.Transaction is null.

There are a couple of issues. First, you have not instantiated new SqlConnection object as in SqlConnection con = new SqlConnection();
Second, unless the container is set to participate in a transaction, Dts.Transaction will be null and so the cast to a SqlConnection will be null. Transactions are supported by default, but unless a parent container starts it, there will be no shared transaction. This makes the examples from MS a little misleading.
I suggest going with the following. Supposing your connection manager is an OleDb connection, the add System.Data.Oledb to the usings:
OleDbConnection conn = new OleDbConnection(Dts.Connections[".\\sql2016.SSISAuditDB"].ConnectionString);
using (conn)
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT 1", conn);
int val = (int)cmd.ExecuteScalar();
MessageBox.Show(val.ToString());
}
In the above code, we just grab the connection string from our connection manager and then create a new connection from it. Note that OleDbConnection implements IDisposable, so it can be wrapped in a using() block and it does not need to be explicitly closed. This is a good practice, because it means you will not need to have extra handling for closing the connection, for example if you added a catch block.
m

You're using SQLNCLI11.1 Provider with SqlConnection object. Change your DTS connection, use "ADO.NET Connection" and try it.

Related

How can this be the same sql connection?

"select LAST_INSERT_ID()" is related to the connection. So i test in Mariadb 5.5.25, code as below:
string strConn = "server=localhost;userid=root;password=admin;database=changde2018;charset=utf8;Allow Zero Datetime=True";
using (MySqlConnection connection = new MySqlConnection(strConn))
{
connection.Open();
MySqlCommand cmd = MySqlCommand("insert into t_data (gid) values(665)", connection);// gid is a autoincrease value
cmd.ExecuteNonQuery();
connection.Close();
}
using (MySqlConnection connection = new MySqlConnection(strConn))
{
DataTable dt2 = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter("select LAST_INSERT_ID()", connection);
da.Fill(dt2);
Console.WriteLine(dt2.Rows[0][0].ToString());//expect 0, but it's as same as the last inserted value
}
I query in navicat by 'show status like 'Threads%''. After exe code above, the 'threads_connected' only increased one. This proves Mariadb does treat them as the same connection. Can this be why, I use two different MySqlConnection objects, is it because of the same connection string?
As mysqlconnector.Net documentation says on connection pooling (highlighting is mine):
The MySQL Connector/Net supports connection pooling for better
performance and scalability with database-intensive applications. This
is enabled by default. You can turn it off or adjust its performance
characteristics using the connection string options Pooling,
Connection Reset, Connection Lifetime, Cache Server Properties, Max
Pool Size and Min Pool Size. See Section 5.1.1, “Creating a
Connector/Net Connection String” for further information.
Connection pooling works by keeping the native connection to the
server live when the client disposes of a MySqlConnection.
Subsequently, if a new MySqlConnection object is opened, it will be
created from the connection pool, rather than creating a new native
connection. This improves performance.
Since connection pooling is turned on by default, the database connection was not closed when you closed and disposed of the first mysqlconnection object and was reused by the next section of the code.
You can fully verify this using the connection_id() function in sql.

Open a connection to a local DB asp.net MVC

I'm trying to open a connection to a DB and then insert a record into a table. At the moment it's just a simple localDB, I have looked at opening the connection with the sqlclient namespace methods.
SqlConnection con = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;
AttachDbFilename=C:\\FILE\\PATH\\EXAMPLE\\TechMVCDB.mdf;Integrated Security=True;
Connect Timeout=30");
I'm not certain that my connection string is even correct, I got it directly from the connection string box when you click on your database in the server explorer panel. I added a breakpoint in the code after the connection was opened and a select all statement was executed :
SqlConnection con = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\FILE\\PATH\\EXAMPLE\\TechMVCDB.mdf;Integrated Security=True;Connect Timeout=30");
con.Open();
SqlCommand com = new SqlCommand();
com.Connection = con;
com.CommandText = "SELECT * FROM Table ORDER BY Id";
SqlDataReader rdr = com.ExecuteReader();
I then get this error "System.Data.SqlClient.SqlException: 'Incorrect syntax near the keyword 'Table'.'" Table was just simply the name of the table was it also treating it as a keyword?
After this I changed the tablename to TechTester and ran it again, it ran with no errors and seemed to get the correct field amount of 4 id,sequence,direction,time it didn't seem to get the inserted test data.
I've also looked at using the Entity framework and implemented the very beginnings of it so I have my entity model class setup but nothing more. Is this the direction I should actually go with? How would I access the entity database?
My question is How do I best open a connection to a local db in asp.net-MVC using C#?
Table is one of the SQL Server reserved keywords.

Database connection succeeds for non-existent databases

Looks like SQLite database connection doesn't actually try to open database connection when I call Open() function. Here's a simple test:
var factory = DbProviderFactories.GetFactory("System.Data.SQLite");
connection = factory.CreateConnection();
connection.ConnectionString = "data source=NonExistentDB.db3";
conn.Open();
The above code does not generate any kind of exception. Moreover, the connection state is Open after this. Is there a way to do "Test Connection" that would physically establish a connection with the database?
Change to
connection.ConnectionString = "data source=NonExistentDB.db3;FailIfMissing=True"
Without the last argument, it will simply create a new database if the file is not found.

the requested operation requires sql clr context

I am getting an error while connecting to the sql from my cs file. I am trying to create CLR functions in c# without using any IDE which is the requirement. I need to access the database to get some value. Following is the code to connect to my database in c#.
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open();
SqlCommand cmd = new SqlCommand(
"SELECT COUNT(*) AS 'Order Count' FROM customer_master with (nolock)", conn);
SqlContext.Pipe.ExecuteAndSend(cmd);
return (int)cmd.ExecuteScalar();
}
but I am getting the following error:
"The requested operation requires a SqlClr context, which is only available when running in the Sql Server process". If i use pipe i don't know how to convert that to an int value. Any suggestions please....
As per this Blog post, try it like this, with the SQLConnection not in a using. The SQLCommand is Disposable and should be in a using though.
SqlConnection conn = new SqlConnection("context connection=true") ;
using(SqlCommand cmd = new SqlCommand(
"SELECT COUNT(*) AS 'Order Count' FROM customer_master with (nolock)", conn))
{
conn.Open();
return (int)cmd.ExecuteScalar();
}
I wrote the below first, but I think the above is the answer, I'm leaving struck out in case it is relevant.
A ContextConnection is a connection back down the existing open connection that the SQL calling the CLR function is using.
To use a SQL CLR Function with a ContextConnection you have to call it from inside a SQL Statement.
e.g. (where CLRConvert is my CLR function that connects back to my database and performs a query and converts stuff).
select dbo.CLRConvert(Data) from MyTables;
If you need to call it outside of here, you will need a proper connection string.

SQL connection to database repeating

ok now i am using the SQL database to get the values from different tables... so i make the connection and get the values like this:
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = ConfigurationManager.ConnectionStrings["XYZConnectionString"].ConnectionString;
connection.Open();
SqlCommand sqlCmd = new SqlCommand("SELECT * FROM Machines", connection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd);
sqlCmd.Parameters.AddWithValue("#node", node);
sqlDa.Fill(dt);
connection.Close();
so this is one query on the page and i am calling many other queries on the page.
So do i need to open and close the connection everytime...???
also if not this portion is common in all:
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection();
connection.ConnectionString = ConfigurationManager.ConnectionStrings["XYZConnectionString"].ConnectionString;
connection.Open();
can i like put it in one function and call it instead.. the code would look cleaner...
i tried doing that but i get errors like:
Connection does not exist in the current context.
any suggestions???
thanks
You can definitely share the "open connection" code, no reason to duplicate it.
With the SQL Server provider for ASP.NET, there is very little overhead with "closing" the connection every time. It just returns the connection to your process' connection pool (see here), so opening the next connection will use very little overhead. I think it is good practice to close the connection after each operation
I use "using". You can include as many queries as you like inside. When complete it will clean up for you.
using (SqlConnection cn = new SqlConnection(connectionString))
{
using (SqlCommand cm = new SqlCommand(commandString, cn))
{
cn.Open();
cm.ExecuteNonQuery();
}
}
Typically yes, you make individual connections for multiple rowsets.
If you can use joins to produce a single meaningful rowset, that's typically a good thing to do on the server side instead of the client side.
You may also want to look at making multiple connections and using the async features in order to queue all your requests simultaneously instead of sequentially - have a look at this article.
No you do not have to open and close the connection every time as long as you are using the same database. What you need to change is the
sqlCommand's queryString every time.
Like what #durilai said, [using] is useful. Using actually has more functions than this, but essentially it puts a try/catch block around your code and calls dispose to close the connection in this case.
Anything that needs open/close can be used with using, so things such as text writers, or other objects.

Categories