calling oracle stored procedure in c# - oracle

I am trying to call a oracle stored procedure in c# like this
OdbcDataAdapter da = new OdbcDataAdapter();
da.SelectCommand = new OdbcCommand();
da.SelectCommand.Connection = con;
da.SelectCommand.Connection.Open();
da.SelectCommand.CommandText = "KAMRAN.ATTN";
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.ExecuteNonQuery();
da.SelectCommand.Connection.Close();
Label3.Text = "Attendance Posted Successfully";
But I am showing this error
ERROR [42000] [Oracle][ODBC][Ora]ORA-00900: invalid SQL statement
Please any One Can tell what exactly i am missing to call this procedure.plz help !

You could try to inverse the statements:
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.CommandText = "KAMRAN.ATTN";
Also, maybe try to add:
da.SelectCommand.Parameters.Clear();
before
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.CommandText = "KAMRAN.ATTN";
I think that you should also use a DataTable
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
Maybe that it should also be an Oracle Data Adapter:
OracleDataAdapter da = new OracleDataAdapter();
da.SelectCommand = new OracleCommand();
So you should have:
OracleDataAdapter da = new OracleDataAdapter();
da.SelectCommand = new OracleCommand();
da.SelectCommand.Connection = con;
da.SelectCommand.Connection.Open();
da.SelectCommand.Parameters.Clear();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.CommandText = "KAMRAN.ATTN";
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
da.SelectCommand.Connection.Close();
I hope this helps in any way.

Related

Sys_Refcursor is null

I have this c# code
public static DataSet Get_Workflow_Def()
{
OracleConnection conn = DatabaseHelper.getOracleConnection();
DataSet dataset = new DataSet();
Log.Info("Opening connection");
conn.Open();
OracleCommand cmd = new OracleCommand("CTS.GET_WORKFLOW_DEF", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("p_Dataset", OracleDbType.RefCursor).Direction =
ParameterDirection.Output;
Log.Info("Executing query");
cmd.ExecuteNonQuery();
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.Fill(dataset);
conn.Close();
return dataset;
}
Calling this procedure
create or replace procedure CTS.GET_WORKFLOW_DEF(p_Dataset OUT
Sys_Refcursor)
as
begin
Open p_Dataset For
Select WKF_ID,
WKF_WORKFLOW_ID,
WKF_WORKFLOW_NAME,
WKF_WORKFLOW_VERSION,
WKF_WORKFLOW_SCHEMA
FROM CTS.WKF_WORKFLOW_MASTER
WHERE WKF_WORKFLOW_ACTIVE = '1'
ORDER BY WKF_ID DESC;
end GET_WORKFLOW_DEF;
If I execute the query I get the information I am looking for but the RefCursor is null. I'm an Oracle newb. Can anyone see where I am going wrong?
Found my problem I needed to add this line before the da.fill(dataset); line and after I instantiated the OracleDataAdapter in my c# code
da.TableMappings.Add("Table",
ConfigurationManager.AppSettings["DBPullTable"].ToString());

SQLDataAdapter and DataSet

I'm requested to work with a bit of code that uses an SqlDataAdapter, and I was wondering if this is the right approach.(I have looked at the documentation, but it's not totally clear in my mind)
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM MY_TABLE";
var Adapter = new SqlDataAdapter(cmd);
DataSet Result = new DataSet();
Adapter.Fill(Result);
Edit : think I found what was missing :
connectionString = help.Get_MyConnectionString();
Connection = new SqlConnection(connectionString);
Connection.Open();
Should work better with the connection open -.-"
Yes you need to open the connection. I would also wrap your SqlConnection and SqlDataAdapter in using blocks so that they are properly disposed.
using (var conn = new SqlConnection("YOUR CONNECTION STRING"))
{
conn.Open();
using (var adapter = new SqlDataAdapter(
"SELECT * FROM MY_TABLE", conn))
{
var result = new DataSet();
adapter.Fill(result);
}
}

Return DataTable from ORACLE

I'm trying to get data from Oracle to a Datatable. My idea was to create a function to do all connection staff and then call it from other parts of the code.
Like:
dt = New DataTable
dt = Oracle2table(sql.ToString)
Then, I created the function:
Function Oracle2table(ByVal sql As String) As DataTable
Oracle2table = Nothing
Try
conn = New OleDb.OleDbConnection(connString)
conn.Open()
cmd = New OleDbCommand(sql, conn)
adaptador = New OleDbDataAdapter
adaptador.SelectCommand = cmd
adaptador.Fill(Oracle2table)
conn.Dispose()
Catch ex As Exception
MessageBox.Show("Error al cargar la tabla. ERROR = " + ex.ToString)
Finally
Oracle2table = Nothing
End Try
End Function
The problem with this code is initialize the variable (Oracle2table = nothing) so i didn't receive a function error.
I am not VB specialist, but this code worked fine, so it may be useful for you:
Dim dt = Oracle2table("select * from dual")
Console.WriteLine(dt.Rows(0)(0))
Function (I removed exception handling for simplicity):
Function Oracle2table(ByVal sql As String) As DataTable
Dim conn = New OleDbConnection(connString)
Oracle2table = New DataTable
conn = New OleDb.OleDbConnection(connString)
conn.Open()
Dim cmd = New OleDbCommand(sql, conn)
Dim adaptador = New OleDbDataAdapter
adaptador.SelectCommand = cmd
adaptador.Fill(Oracle2table)
conn.Dispose()
End Function

my code gets this error:One or more errors occurred during processing of command

I have problem with running this:
i captured picture from my win
OleDbConnection con = new OleDbConnection();
DataTable dt = new DataTable();
con.ConnectionString = "Provider=MSDAORA;Data Source=DATA;Password=ss8_pakhsh;User ID=SHIFTS_N";
con.Open();
string sqlcommand = "INSERT INTO GROUPS(GROUP_ID, GROUP_NAME,DEPT_ID) " +
"VALUES(SEQ_MAX_GROUP_ID_NO.NEXTVAL,#groupName,SELECT
DEPT_ID FROM PERSONNEL_TEMP.DEPARTMENT WHERE
DEPARTMENT_NAME=#depName)";
OleDbCommand command = new OleDbCommand(sqlcommand, con);
command.Parameters.AddWithValue("#groupName", textBox1.Text);
command.Parameters.AddWithValue("#depName", comboBox1.SelectedItem);
OleDbDataAdapter oda = new OleDbDataAdapter(command);
oda.Fill(dt);
dataGridView2.DataSource = dt;
con.Close();
Change the sqlcommand string as shown below,
string sqlcommand = "INSERT INTO GROUPS(GROUP_ID, GROUP_NAME,DEPT_ID) " +
"VALUES(SEQ_MAX_GROUP_ID_NO.NEXTVAL,#groupName,SELECT "+
"DEPT_ID FROM PERSONNEL_TEMP.DEPARTMENT WHERE "+
"DEPARTMENT_NAME=#depName)";
This should solve the issue.
Observation: It is not a good practice to directly set the textBox1.Text value in parameter.

MiniProfiler - ProfiledDbDataAdapter

Trying to get MiniProfiler to profile loading a DataTable via a Stored Proc
// Use a DbDataAdapter to return data from a SP using a DataTable
var sqlConnection = new SqlConnection(#"server=.\SQLEXPRESS;database=TestDB;Trusted_Connection=True;");
DbConnection connection = new StackExchange.Profiling.Data.ProfiledDbConnection(sqlConnection, MiniProfiler.Current);
var table = new DataTable();
DbDataAdapter dataAdapter = new SqlDataAdapter("GetCountries", sqlConnection);
ProfiledDbDataAdapter prdataAdapter = new ProfiledDbDataAdapter(dataAdapter, null);
// null reference exception here - SelectCommand is null
prdataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
prdataAdapter.SelectCommand.Parameters.Add(new SqlParameter("#countryID", 2));
prdataAdapter.Fill(table);
ViewBag.table = table;
Problem: Null reference exception on SelectCommand
Please ignore lack of usings / disposing
I can successfully profile using ProfiledDbCommand to a SP:
// call a SP from DbCommand
var sqlConnection2 = new SqlConnection(#"server=.\SQLEXPRESS;database=TestDB;Trusted_Connection=True;");
DbConnection connection2 = new StackExchange.Profiling.Data.ProfiledDbConnection(sqlConnection2, MiniProfiler.Current);
if (connection2 != null)
{
using (connection2)
{
try
{
// Create the command.
DbCommand command = new SqlCommand();
ProfiledDbCommand prcommand = new ProfiledDbCommand(command, connection2, null);
prcommand.CommandType = CommandType.StoredProcedure;
prcommand.CommandText = "dbo.GetCountries";
prcommand.Parameters.Add(new SqlParameter("#countryID", 3));
prcommand.Connection = connection2;
//command.CommandText = "SELECT Name FROM Countries";
//command.CommandType = CommandType.Text;
// Open the connection.
connection2.Open();
// Retrieve the data.
DbDataReader reader = prcommand.ExecuteReader();
while (reader.Read())
{
var text = reader["Name"];
result += text + ", ";
}
}
catch (Exception ex)
{
}
}
}
Edit1:
This works:
// 2) SqlConnection, SqlDataAdapter.. dataAdapter command - works
var sqlConnection = new SqlConnection(#"server=.\SQLEXPRESS;database=TestDB;Trusted_Connection=True;");
var table = new DataTable();
//var dataAdapter = new SqlDataAdapter("GetCountries", sqlConnection);
var dataAdapter = new SqlDataAdapter("select * from countries", sqlConnection);
//dataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
//dataAdapter.SelectCommand.Parameters.AddWithValue("#countryID", 2);
dataAdapter.Fill(table);
This doesn't DataTable.. but does with DataSet
var sqlConnection = new SqlConnection(#"server=.\SQLEXPRESS;database=TestDB;Trusted_Connection=True;");
DbConnection connection = new ProfiledDbConnection(sqlConnection, MiniProfiler.Current);
DbDataAdapter dataAdapter = new SqlDataAdapter("select * from countries", sqlConnection);
ProfiledDbDataAdapter prdataAdapter = new ProfiledDbDataAdapter(dataAdapter, null);
var table = new DataTable();
var dataset = new DataSet();
// Doesn't work
//prdataAdapter.Fill(table);
// Does work
prdataAdapter.Fill(dataset);
It turns out that though ProfiledDbDataAdapter inherited from DbDataAdapter, it did not override the default functionality of DbDataAdapter.Fill(DataTable), leading to the errors that you saw.
I fixed this in the MiniProfiler code. Fix is available in nuget, version 3.0.10-beta7 and higher.
I have tested this with your code from above and it works for me:
DbConnection connection =
new ProfiledDbConnection(sqlConnection, MiniProfiler.Current);
var sql = "select * from countries";
DbDataAdapter dataAdapter = new SqlDataAdapter(sql, sqlConnection);
ProfiledDbDataAdapter prdataAdapter = new ProfiledDbDataAdapter(dataAdapter);
var table = new DataTable();
dataAdapter.Fill(table); // this now works

Resources