C# эквивалент подготовленного заявления Java
Я пытаюсь создать готовый оператор в C#.
По какой-то причине все, что я пробую, заканчивается исключением.
Это мой код сейчас:
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();
}
Я получаю исключение: "Операция недействительна из-за текущего состояния объекта".
2 ответа
Типичное подготовленное Oracle заявление выглядит следующим образом.
(обратите внимание, что только определение в подготовленном утверждении имеет :
двоеточие, и тот, в cmd.Parameters.AddWithValue
звонить не надо)
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();
}
Я бы предложил сделать это так:
//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();
}
Я создал строку подключения в моем файле web.config, продемонстрированном здесь.
Во-первых, ваш код не будет компилироваться, потому что
:message
не является допустимым идентификатором C#. Строка, добавляющая параметр, должна быть:
cmd.Parameters.Add(":message", msg);
Во-вторых, эффективнее регистрировать параметры на этапе подготовки:
par = cmd.CreateParameter();
par.ParameterName = ":message";
cmd.Parameters.Add( par );
и укажите значение при каждом вызове подготовленного запроса:
cmd.Parameters[i].Value = message;
если вы следите за своими параметрами, и
cmd.Parameters[":message"].Value = message;
если нет.
В-третьих
Prepare()
метод в ODP.NET ничего не делает. Он нужен только для удовлетворения интерфейса IDbCommand, который требует Prepare()
метод. Весьма прискорбно, что хотя Oracle были реализованы подготовить функциональность родного JDBC - интерфейс, они не отказались от него в ADO.NET. С другой стороны, ODP.NET рекламируется для локального кеширования повторяющихся запросов, что должно немного помочь.
Что касается исключения, которое вы получаете, я думаю, что это не имеет ничего общего с
.Prepare()
. Попробуйте использовать тот же код без него и посмотрите, сохраняется ли исключение. Наиболее вероятная причина - ваше соединение не открыто, поэтому оно не будет работать независимо от
.Prepare()
.