3

I am trying to create a prepared statement in c#.

For some reason everything I try ends up with an exeption.

This is my code for now:

using (OracleCommand cmd = new OracleCommand())
{
    cmd.Connection = conn;
    cmd.CommandType = CommandType.Text;

    cmd.CommandText = "insert into daily_cdr_logs " +
            "(message) " +
            "values " +
            "(:message)";

    cmd.Parameters.Add(:message, msg);
    //OracleDbType.Int32, postpaid_duration, ParameterDirection.Input);
    cmd.Prepare();
    cmd.ExecuteNonQuery();
}

I am getting exeption: "Operation is not valid due to the current state of the object."

susparsy
  • 1,016
  • 5
  • 22
  • 38

3 Answers3

2

A typical Oracle prepared statement looks like this.

(notice that only the definition in the prepared statement has the : colon, and the one in the cmd.Parameters.AddWithValue call does not)

String msg = "something here";

using (OracleConnection con = new OracleConnection(...insert connection params here...))
{
  con.Open();
  OracleCommand cmd = con.CreateCommand();
  cmd.CommandType = CommandType.Text;
  cmd.CommandText = @"
        insert into daily_cdr_logs
        (message) 
        values 
        (:message)";
  cmd.Parameters.AddWithValue("message", msg);
  cmd.ExecuteNonQuery();
}
Timothy Groote
  • 8,614
  • 26
  • 52
0

I would suggest doing it like this:

//create a connection
string conString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionName"].ConnectionString;
OracleConnection con = new OracleConnection(conString);

//create SQL and insert parameters
OracleCommand cmd = new OracleCommand("insert into daily_cdr_logs (message) values (:_message)", con);
cmd.Parameters.Add(new OracleParameter("_message", msg));

    try
    {
        //if connection is closed, open it
        if (con.State == ConnectionState.Closed)
             con.Open();

             //execute query
             cmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
         //do something with the error
    }
    finally
    {
         //if connection is open, close it
         if (con.State == ConnectionState.Open)
         con.Close();
    }

I have created my connection string in my web.config file, demonstrated here.

Community
  • 1
  • 1
Alex
  • 1,082
  • 3
  • 12
  • 23
0

First—your code will not compile, because :message is not a valid C# identifier. The line adding the parameter should be:

cmd.Parameters.Add(":message", msg);

Second—it is more efficient to register parameters at the prepare stage:

par = cmd.CreateParameter();
par.ParameterName = ":message";
cmd.Parameters.Add( par ); 

and supply the value in each invocation of the prepared query:

cmd.Parameters[i].Value = message;

if you keep track of your parameters, and

cmd.Parameters[":message"].Value = message;

if you don't.

Third—the Prepare() method in ODP.NET does nothing. It is there only to satisfy the IDbCommand interface, that requres a Prepare() method. It is rather deplorable that although Oracle have implemented the prepare functionality for the native JDBC interface, they decided not against it for ADO.NET. On the other hand, ODP.NET is advertised to cache repeating queries locally, which should help a bit.

As to the exception you are getting, I think it has nothing to do with .Prepare(). Try the same code without it and see if the exception remains. The most probable cause is that your connection is not open, so that it will not work regardless of .Prepare().

Anton Shepelev
  • 922
  • 9
  • 19