Connect to remote oracle database using odac - c#

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();
}

Related

Oracle connection getting time out

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;

Best practices with oracle connection in C #

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

exception in acquiring data - C# with OracleDB

static public void ConnectAndQuery()
{
string connectionString = GetConnectionString();
using (OracleConnection conn = new OracleConnection())
{
conn.ConnectionString = connectionString;
conn.Open();
Console.WriteLine("State: " + conn.State);
Console.WriteLine("Connection String: " + conn.ConnectionString);
OracleCommand command = conn.CreateCommand();
string sql = "SELECT * FROM users";
command.CommandText = sql;
OracleDataReader reader = command.ExecuteReader();
while (reader.Read())
{
string myField = (string)reader["MYFIELD"];
Console.WriteLine(myField);
}
}
}
The connection is established and working open but I get IndexOutOfRangeException when trying to acquire the data from the DB. The exception is caught on
string myField = (string)reader["MYFIELD"];
I looked for info about the OracleDataReader and the command in order to understand the reader, but... does it store the data acquired in an array or any other sequence ? Why am I getting the IndexOutOfRangeException and why does the reader require an argument in the [] brackets?
You probably do not have a field that is called MYFIELD. Remember that the field names are case sensitive... Try using an index instead i.e. reader[0]

Query using Oracle Parameter returns no result 11g

A simple select statement using variable binding gives no rows??
OracleConnection con = new OracleConnection(constr);
con.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = con;
cmd.CommandText = "select country_name from hr.countries where country_id = :country_id;
OracleParameter p_country_id = new OracleParameter();
p_country_id.OracleDbType = OracleDbType.Varchar2;
p_country_id.Value = "UK";
cmd.Parameters.Add(p_country_id);
OracleDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{} ---> no rows
tried adding parameterName ,direction,size still result is 0???
Any help??
I believe this is all correct but it is written in NotePad. At the very least it should get you on the right track.
using (OracleConnection con = new OracleConnection(constr))
{
con.Open();
using (OracleCommand cmd = con.CreateCommand())
{
cmd.CommandText = "select country_name from hr.countries where country_id = :country_id";
cmd.Parameters.Add("country_id", "UK")
OracleDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
// You code here
}
}
}
NOTE: I put the using statements in there because this is always recommended when executing database queries. If an exception occurs the using statement will guarantee your database connection is still closed.
You forgot to give your parameter a name. Do so and it should work:
p_country_id.ParameterName = "country_id";
Thanks for responding guys, My unit test project app.config was pointing to wrong DB schema :(
Grrrrrrrrrrrrr! can't get anything stupid then this :) i will blame on my flu :)

Using a existing connection in a Script Component (SSIS)

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();

Categories

Resources