I have an application which query database at a specific time of day and then it idle for next 3-4 hours and then again it queries database for some data but it is being executed only once and at the second attempt it is throwing an error.
using (OracleConnection connection = new OracleConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
OracleCommand command = connection.CreateCommand();
string sql = _query;
command.CommandText = sql;
OracleDataAdapter oAdapter = new OracleDataAdapter(sql, connection);
oAdapter.Fill(myDataSet);
connection.Close();
return myDataSet;
}
The Error is being thrown at:
oAdapter.Fill(myDataSet);
And error stats as ORA-03113: end-of-file on communication channel
To my understanding connection should be disposed after one call and it should create another connection on each request. I have checked that the connection to the server is available and listening, no network issues while this error is occurring.
I got it, For any one else looking for answer is that I was calling return myDataSet; inside the using statement first i didn't notice it but as OracleConnection is being inherited from IDisposable and i was returning dataset inside using statement so it was never getting disposed off properly. so i just changed this from
using (OracleConnection connection = new OracleConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
OracleCommand command = connection.CreateCommand();
string sql = _query;
command.CommandText = sql;
OracleDataAdapter oAdapter = new OracleDataAdapter(sql, connection);
oAdapter.Fill(myDataSet);
connection.Close();
return myDataSet;}
to
using (OracleConnection connection = new OracleConnection()){
connection.ConnectionString = connectionString;
connection.Open();
OracleCommand command = connection.CreateCommand();
string sql = _query;
command.CommandText = sql;
OracleDataAdapter oAdapter = new OracleDataAdapter(sql, connection);
oAdapter.Fill(myDataSet);
connection.Close(); }
return myDataSet;
Related
I'm playing around making a POC and I've created the following call.
public string DoStuff()
{
try
{
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
SqlConnection connection = new SqlConnection("Server...");
string command = "insert into Records values (...)";
adapter.InsertCommand = new SqlCommand(command, connection);
}
}
catch (Exception exception)
{
return exception.Message + " " + exception.InnerException;
}
return "WeeHee!";
}
The text I'm seeing returned is the happy one, so I conclude there's no exceptions. Hence, I conclude that the call to the DB is performed as supposed to. However, there's no new lines in the DB being created.
I'm using the same connection string as I have in my config file and the command in pasted in from SQL Manager, where it works.
So my suspicion was that although I create an insert command, I never actually execute it but according to MSDN that's how it's supposed to work.
What stupid thing do I miss here?
You are missing connection.Open(); and adapter.InsertCommand.ExecuteNonQuery();
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
SqlConnection connection = new SqlConnection("Server...");
connection.Open();
string command = "insert into Records values (...)";
adapter.InsertCommand = new SqlCommand(command, connection);
adapter.InsertCommand.ExecuteNonQuery();
}
You should use ExecuteNonQuery instead. Using an SqlDataAdapter for an INSERT query does not make sense.
Also you should Open your connection just before you execute it.
You can:
using(SqlConnection connection = new SqlConnection("Server..."))
{
SqlCommand command = connection.CreateCommand();
command.CommandText = "insert into Records values (...)";
connection.Open();
int craeted = command.ExecuteNonQuery();
}
The example you linked to returned a SQLAdapter for later use.
You don't need one at all:
using (SqlConnection connection = new SqlConnection("Server..."))
{
string command = "insert into Records values (...)";
connection.Open();
var command = new SqlCommand(command, connection);
command.ExecuteNonQuery();
}
Note that there are other execution methods, depending on expected return values and whether you want asynchronous operation: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand(v=vs.110).aspx
I need to make asmx web service. I installed ODAC from here
Then, i add references to my project:
1) Oracle.DataAccess
2) Oracle.Web
[WebMethod]
public string EaaTest(string r_object_id)
{
string connString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)" +
"(HOST=my host)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=dcmt)));" +
"User Id=my id ;Password=my password;"
using (OracleConnection conn = new OracleConnection(connString))
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = string.Format("select DSS_TITLE_RU from DBREP36.DDT_DA_DIRECTION_S where R_OBJECT_ID=0", r_object_id);
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
string result = dr.GetString(0);
return result;
}
}
Now, i have exception:
An exception of type 'System.InvalidOperationException' occurred in
Oracle.DataAccess.dll but was not handled in user code
Additional information: Connection must be open for this operation
On line: OracleDataReader dr = cmd.ExecuteReader();
Error message isn't clear at all?
Connection must be open for this operation
You need to open your connection before you execute your command.
conn.Open();
OracleDataReader dr = cmd.ExecuteReader();
Use using statement to dispose your command and reader as you did for your connection.
By the way, you didn't specify zero index in your string.Format. Your
where R_OBJECT_ID=0
should be
where R_OBJECT_ID = {0}
As a better option, use parameterized queries. Any kind of string concatenations are open for SQL Injection attacks.
Since you return just first column of the first row, use ExecuteScalar instead which is exactly what this for.
using(var conn = new OracleConnection(connString))
using(var cmd = conn.CreateCommand())
{
cmd.CommandText = #"select DSS_TITLE_RU from DBREP36.DDT_DA_DIRECTION_S
where R_OBJECT_ID = #id";
cmd.Parameters.AddWithValue(#id, r_object_id);
conn.Open();
return (string)cmd.ExecuteScalar();
}
Fill: SelectCommand.Connection property has not been initialized. I have done the coding in button click. Conn is my connection class's object. I have called this connection class in my button click class. Let me know why it shows error? I have already searched answer for this question in Stack overflow and I applied even though it shows the same error. The ddcode.selectedItem.Text is dropdown for select Employee name.
string strQuery = "SELECT MachID, EmpCode, FROM LeaveApply where MachID='" + ddcode.SelectedItem.Text + "'",conn;
SqlCommand cmd = new SqlCommand(strQuery);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
See it is my connection class
public Connection()
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString);
cmd = null;
}
And I have called this connection class in my button click function's class like
Connection conn = new Connection();
There's no point actually creating a SqlCommand object because the SqlDataAdapter will do it for you. In fact, it can even create the SqlConnection object for you. If you need to reuse the connection then do this:
using (var connection = new SqlConnection(connectionString))
using (var adapter = new SqlDataAdapter(query, connection))
{
adapter.SelectCommand.Parameters.AddWithValue(paramName, paramValue);
// ...
}
and, if you don't need to reuse the connection then do this:
using (var adapter = new SqlDataAdapter(query, connectionString))
{
adapter.SelectCommand.Parameters.AddWithValue(paramName, paramValue);
// ...
}
If you really want to create a separate SqlCommand then do this:
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(query, connection))
using (var adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue(paramName, paramValue);
// ...
}
I would recommend using the CreateCommand factory method of the connection object to create your command, then your command object will correctly use the connection object.
SqlConnection conn = new SqlConnection("ConnectionString");
conn.Open(); // Make sure connection is open.
string strQuery = "SELECT MachID, EmpCode, FROM LeaveApply where MachID='" + selectedItem + "'";
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = strQuery;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
Alternatively you can manually tell the command to use the connection object
cmd.Connection = conn;
It sounds like jmcilhinney has a better answer for your purposes however.
You are missing the connection to your database. The connection will perform the following jobs.
Create a connection to database by using provided connection string.
Open up the connection bridge to transact the data.
Execute the provided query or Stored Procedure.
Fill the data in application's memory
Close the connection bridge to prevent the database.
Use the object of your own connection class.
Try it as follows:
using (Connection Con = new Connection()) {
SqlCommand cmd = new SqlCommand(strQuery);
cmd.Connection = Con;
SqlDataAdapter sda = new SqlDataAdapter(cmd);
try {
Con.Open();
sda.SelectCommand = cmd;
sda.Fill(dt);
Con.Close();
} catch (Exception ex) {
}
We use oracle database connection and our class database access does not have a dispose or close. It interferes with something or performance of the application? I saw this example:
string oradb = "Data Source=ORCL;User Id=hr;Password=hr;";
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "select * from departments";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
label1.Text = dr.GetString(0);
conn.Dispose();
And I realized that it opens the connection and then kills her. This is correct? Is there any other better?
I'm leaving my connection open and then ends up being closed for a while. I think that's it. This so wrong?
Use the Using statement with disposable objects. In particular with any kind of connection and datareaders
string oradb = "Data Source=ORCL;User Id=hr;Password=hr;";
using(OracleConnection conn = new OracleConnection(oradb))
using(OracleCommand cmd = new OracleCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select * from departments";
cmd.CommandType = CommandType.Text;
using(OracleDataReader dr = cmd.ExecuteReader())
{
dr.Read();
label1.Text = dr.GetString(0);
}
}
Here you could read about the Using statement and why it is important. Regarding the connection and readers, you should enclose the objects with the using statement to be sure that everything is properly closed and disposed when you exit from the using block ALSO in case of exceptions
I have am OLEDB Connection configured in the connection managers and I want to use it in a SCRIPT. The script needs to call a stored proc and then create buffer rows. I have added the connection to the connections available to the script and this is my code.
Boolean fireagain = true;
SqlConnection conn = new SqlConnection();
conn = (SqlConnection)(Connections.Connection
.AcquireConnection(null) as SqlConnection);
SqlCommand cmd = new SqlCommand();
conn.Open();
ComponentMetaData.FireInformation(
0, "Script", "Connection Open", string.Empty, 0, ref fireagain);
cmd.Connection = conn;
cmd.CommandText = "up_FullTextParser_select" ;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("Phrase", DbType.String).Value = Row.Keywords;
cmd.Parameters.AddWithValue("SpecialTerm", DbType.String).Value = "Exact match";
cmd.Parameters.AddWithValue("StopListId", DbType.Int32).Value = 0;
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (rdr.Read())
{
TermsBuffer.AddRow();
TermsBuffer.Term = rdr[0].ToString();
}
conn.Close();
Anyway, it seems to fail on the AcquireConnection. Am I converting this wrong? Should I be using a different way to using the connections defined outside the script?.
You cannot cast an OLEDB connection to SqlConnection object. You must use the OleDbConnection object. See the example - http://blogs.msdn.com/b/mattm/archive/2008/08/22/accessing-oledb-connection-managers-in-a-script.aspx
This MSDN example implies that you using AcquireConnection incorrectly.
You need to use a managed connection provider.
If you insist on using an OLEDB connection, you cannot use AcquireConnection but you can extract the connection string and then use it to create an OLEDB connection:
string connstr = Dts.Connections["my_OLEDB_connection"].ConnectionString;
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(connstr);
This may not work if the connection string is created via an expression of some sort.
IDTSConnectionManager100 connMgr = this.Connections.ADONetAppStaging ; //this we need to give name in connection manager in script component
SqlConnection myADONETConnection = new SqlConnection();
myADONETConnection = (SqlConnection)(connMgr.AcquireConnection(null));
//Read data from table or view to data table
string query = "Select top 10 * From ##AP_Stagging_Temp_ExportWODuplicates Order by 1,2,3 asc ";
// string query = "Select * From ##AP_Stagging_Temp_For_JLL_ExportWODuplicates order by 1,2,3 asc ";
SqlDataAdapter adapter = new SqlDataAdapter(query, myADONETConnection);
datatable dtExcelData = new datatable();
adapter.Fill(dtExcelData);
myADONETConnection.Close();