C#中与Java prepared statement相当的内容

3

我正在尝试在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();
}

我遇到了异常:“由于对象的当前状态无效,操作无法执行。”

1
没有分享异常的详细信息,我们无法提供太多帮助。 - Oded
“an exception” - 是哪一个?你能给出这些异常的类型和消息吗? - Damien_The_Unbeliever
1
显示了什么异常?还有可能是个愚蠢的问题,但你在使用连接之前是否打开了它(conn.Open())? - BudBrot
尝试在 Parameters.Add 调用和打开连接之前移动 Prepare 调用。 - Viacheslav Smityukh
尝试使用 cmd.Parameters.Add(":message", msg); 没有起作用。 - susparsy
显示剩余6条评论
3个回答

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

我已经有一个打开的连接,但它找不到AddWithValue。 - susparsy
传递给 AddWithValue(string, object) 的参数名称可能已经带有冒号,也可能没有。这是可选的。 - Anton Shepelev

0
我建议这样做:
//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 文件中创建了连接字符串,示例 在此处


0

首先,你的代码无法编译,因为: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;

如果你不这样做。

第三点——在ODP.NET中,Prepare()方法没有实际作用。它只是为了满足IDbCommand接口的要求,该接口需要一个Prepare()方法。虽然Oracle已经实现了本地JDBC接口的准备功能,但他们决定不在ADO.NET中使用。另一方面,ODP.NET被宣传为可以在本地缓存重复查询,这应该会有所帮助。

关于您遇到的异常,我认为它与.Prepare()无关。尝试不使用它运行相同的代码,看看异常是否仍然存在。最有可能的原因是您的连接没有打开,因此无论.Prepare()是否工作都不会起作用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接