34

How does one call a stored procedure in oracle from C#?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Rohan
  • 1,960
  • 3
  • 22
  • 30
  • 2
    Can you post the stored procedure? What libraries are you using to connect to the DB? ADO.NET? An ORM (nHibernate, EF)? You need to provide lots more detail if you want an answer that will suit your needs. – Oded Oct 15 '10 at 08:24
  • If you expect a Oracle-specific answer, please tag your question as Oracle. Thank you ! – tsimbalar Oct 15 '10 at 08:26
  • I have used basic SQL queries before. However, now I wanted to call Oracle Procedures already written, using C# code. – Rohan Oct 15 '10 at 10:18

8 Answers8

38

Please visit this ODP site set up by oracle for Microsoft OracleClient Developers: http://www.oracle.com/technetwork/topics/dotnet/index-085703.html

Also below is a sample code that can get you started to call a stored procedure from C# to Oracle. PKG_COLLECTION.CSP_COLLECTION_HDR_SELECT is the stored procedure built on Oracle accepting parameters PUNIT, POFFICE, PRECEIPT_NBR and returning the result in T_CURSOR.

using Oracle.DataAccess;
using Oracle.DataAccess.Client;

public DataTable GetHeader_BySproc(string unit, string office, string receiptno)
{
    using (OracleConnection cn = new OracleConnection(DatabaseHelper.GetConnectionString()))
    {
        OracleDataAdapter da = new OracleDataAdapter();
        OracleCommand cmd = new OracleCommand();
        cmd.Connection = cn;
        cmd.InitialLONGFetchSize = 1000;
        cmd.CommandText = DatabaseHelper.GetDBOwner() + "PKG_COLLECTION.CSP_COLLECTION_HDR_SELECT";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("PUNIT", OracleDbType.Char).Value = unit;
        cmd.Parameters.Add("POFFICE", OracleDbType.Char).Value = office;
        cmd.Parameters.Add("PRECEIPT_NBR", OracleDbType.Int32).Value = receiptno;
        cmd.Parameters.Add("T_CURSOR", OracleDbType.RefCursor).Direction = ParameterDirection.Output;

        da.SelectCommand = cmd;
        DataTable dt = new DataTable();
        da.Fill(dt);
        return dt;
    }
}
EvilTeach
  • 28,120
  • 21
  • 85
  • 141
hyperkittie
  • 641
  • 6
  • 16
  • Why is `InitialLONGFetchSize = 1000` preferred? From the DOCS `Default = 0. Setting this property to 0 defers the LONG and LONG RAW data retrieval entirely until the application specifically requests it.` – KLIM8D Oct 01 '15 at 07:32
23

I have now got the steps needed to call procedure from C#

   //GIVE PROCEDURE NAME
   cmd = new OracleCommand("PROCEDURE_NAME", con);
   cmd.CommandType = CommandType.StoredProcedure;

   //ASSIGN PARAMETERS TO BE PASSED
   cmd.Parameters.Add("PARAM1",OracleDbType.Varchar2).Value = VAL1;
   cmd.Parameters.Add("PARAM2",OracleDbType.Varchar2).Value = VAL2;

   //THIS PARAMETER MAY BE USED TO RETURN RESULT OF PROCEDURE CALL
   cmd.Parameters.Add("vSUCCESS", OracleDbType.Varchar2, 1);
   cmd.Parameters["vSUCCESS"].Direction = ParameterDirection.Output;

   //USE THIS PARAMETER CASE CURSOR IS RETURNED FROM PROCEDURE
   cmd.Parameters.Add("vCHASSIS_RESULT",OracleDbType.RefCursor,ParameterDirection.InputOutput); 

   //CALL PROCEDURE
   con.Open();
   OracleDataAdapter da = new OracleDataAdapter(cmd);
   cmd.ExecuteNonQuery();

   //RETURN VALUE
   if (cmd.Parameters["vSUCCESS"].Value.ToString().Equals("T"))
   {
      //YOUR CODE
   }
   //OR
   //IN CASE CURSOR IS TO BE USED, STORE IT IN DATATABLE
   con.Open();
   OracleDataAdapter da = new OracleDataAdapter(cmd);
   da.Fill(dt);

Hope this helps

Maxime
  • 8,645
  • 5
  • 50
  • 53
Rohan
  • 1,960
  • 3
  • 22
  • 30
8

It's basically the same mechanism as for a non query command with:

  • command.CommandText = the name of the stored procedure
  • command.CommandType = CommandType.StoredProcedure
  • As many calls to command.Parameters.Add as the number of parameters the sp requires
  • command.ExecuteNonQuery

There are plenty of examples out there, the first one returned by Google is this one

There's also a little trap you might fall into, if your SP is a function, your return value parameter must be first in the parameters collection

vc 74
  • 37,131
  • 7
  • 73
  • 89
8

Connecting to Oracle is ugly. Here is some cleaner code with a using statement. A lot of the other samples don't call the IDisposable Methods on the objects they create.

using (OracleConnection connection = new OracleConnection("ConnectionString"))
    using (OracleCommand command = new OracleCommand("ProcName", connection))             
    {
          command.CommandType = CommandType.StoredProcedure;
          command.Parameters.Add("ParameterName", OracleDbType.Varchar2).Value = "Your Data Here";
          command.Parameters.Add("SomeOutVar", OracleDbType.Varchar2, 120);
          command.Parameters["return_out"].Direction = ParameterDirection.Output;
          command.Parameters.Add("SomeOutVar1", OracleDbType.Varchar2, 120);
          command.Parameters["return_out2"].Direction = ParameterDirection.Output;
          connection.Open();
          command.ExecuteNonQuery();
          string SomeOutVar = command.Parameters["SomeOutVar"].Value.ToString();
          string SomeOutVar1 = command.Parameters["SomeOutVar1"].Value.ToString();
    }
Robert Stokes
  • 335
  • 4
  • 7
7

This Code works well for me calling oracle stored procedure

Add references by right clicking on your project name in solution explorer >Add Reference >.Net then Add namespaces.

using System.Data.OracleClient;
using System.Data;

then paste this code in event Handler

        string str = "User ID=username;Password=password;Data Source=Test";
        OracleConnection conn = new OracleConnection(str);
        OracleCommand cmd = new OracleCommand("stored_procedure_name", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        --Ad parameter list--
        cmd.Parameters.Add("parameter_name", "varchar2").Value = value;
        ....
        conn.Open();
        cmd.ExecuteNonQuery();

And its Done...Happy Coding with C#

Abdul
  • 854
  • 1
  • 9
  • 11
3

In .Net through version 4 this can be done the same way as for SQL Server Stored Procs but note that you need:

using System.Data.OracleClient;

There are some system requirements here that you should verify are OK in your scenario.

Microsoft is deprecating this namespace as of .Net 4 so third-party providers will be needed in the future. With this in mind, you may be better off using Oracle Data Provider for .Net (ODP.NET) from the word go - this has optimizations that are not in the Microsoft classes. There are other third-party options, but Oracle has a strong vested interest in keeping .Net developers on board so theirs should be good.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
2

Instead of

cmd = new OracleCommand("ProcName", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("ParName", OracleDbType.Varchar2, ParameterDirection.Input).Value = "foo";

You can also use this syntax:

cmd = new OracleCommand("BEGIN ProcName(:p0); END;", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("ParName", OracleDbType.Varchar2, ParameterDirection.Input).Value = "foo";

Note, if you set cmd.BindByName = False (which is the default) then you have to add the parameters in the same order as they are written in your command string, the actual names are not relevant. For cmd.BindByName = True the parameter names have to match, the order does not matter.

In case of a function call the command string would be like this:

cmd = new OracleCommand("BEGIN :ret := ProcName(:ParName); END;", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("ret", OracleDbType.RefCursor, ParameterDirection.ReturnValue);    
cmd.Parameters.Add("ParName", OracleDbType.Varchar2, ParameterDirection.Input).Value = "foo";
// cmd.ExecuteNonQuery(); is not needed, otherwise the function is executed twice!
var da = new OracleDataAdapter(cmd);
da.Fill(dt);
Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
0

Below worked for me in .NET Core solution. Note that it uses OracleDataReader and Oracle CommandType is CommandType.Text

using Oracle.ManagedDataAccess.Client;

.......

                string spSql = "BEGIN STORED_PROC_NAME(:IN_PARAM, :OUT_PARAM1, :OUT_PARAM2); END; ";

                using (OracleConnection oraCnn = new OracleConnection(cnnString))
                using (OracleCommand oraCommand = new OracleCommand(spSql, oraCnn))
                {
                    await oraCnn.OpenAsync(cancellationToken);
                    oraCommand.CommandType = CommandType.Text;
                    oraCommand.BindByName = true;

                    oraCommand.Parameters.Add("IN_PARAM", OracleDbType.Long, ParameterDirection.Input).Value = 123;
                    oraCommand.Parameters.Add("OUT_PARAM1", OracleDbType.Int32, null, ParameterDirection.Output);
                    oraCommand.Parameters.Add("OUT_PARAM2", OracleDbType.Varchar2, 4000, null, ParameterDirection.Output);

                    OracleDataReader objReader = oraCommand.ExecuteReader();

                    string outParamValue= oraCommand.Parameters["OUT_PARAM2"].Value.ToString();
                }