【问题标题】:Return an sql variable's value from within an Oracle Sql Query back to .NET code将 Oracle Sql 查询中的 sql 变量值返回给 .NET 代码
【发布时间】:2012-08-26 06:40:23
【问题描述】:

在过去的几个小时里,我试图通过使用 ADO.NET 的 .NET 应用程序在 Oracle 数据库中做最简单的事情(至少对于 SQL SERVER)。这似乎是不可能的。

对于 SQL SERVER,我会做这个简单的任务,假设我有一个 SqlCommand 对象

comm.CommandText = @"
   DECLARE @next_id INT
   SET @next_id = (SELECT ISNULL(MAX(id_col),0) FROM TABLE_1) + 1
   INSERT INTO TABLE_1 (id_col, col1, ...) VALUES (@next_id, val1, ...)
   SELECT @next_id";
int id = Convert.ToInt32(comm.ExecuteScalar());

这会在表 TABLE_1 中插入一条新记录,然后我会在 c# 代码的“id”变量中取回新的 id。

四个简单的步骤

  • 声明一个变量
  • 将其设置为下一个可用的 id
  • 插入带有新变量的记录
  • 返回变量的值

好的,我设法在 Oracle 查询中声明了变量。我也(认为)我设法给它一个值(使用 SELECT INTO)

如何在 c# 中取回这个变量的值?如何在 Oracle SQL 的输出流中选择一个变量的值?

我知道有更好的方法来实现取回身份列,但这不是这里的问题。这可能是一个完全不同的例子。问题很简单。:我在 oracle sql 脚本中声明了一个变量,该脚本将从 .net 应用程序中执行。 如何从 oracle 查询中将变量的值返回给 c#? 上面的代码与 Oracle ADO.NET 查询的等价物是什么?

【问题讨论】:

    标签: c# oracle variables select ado.net


    【解决方案1】:

    您需要使用ODP.NET(Oracle 的 Oracle 数据访问组件):

    下面是一个例子。请注意,在 ODP.NET 中,您可以建立参数方向(输入、输入输出、输出、返回值)以与您正在运行的过程或语句的参数相对应。在此示例中,我获取了一个返回值,它是 db 通过序列和触发器生成的 ID(就 .NET 应用程序而言,它是自动创建的):

    int event_id = 0;
    using (OracleConnection oraConn = new OracleConnection(connStr))
    {
        string cmdText = @"insert into EVENT
            (EVENT_NAME, EVENT_DESC)
            values
            (:EVENT_NAME, :EVENT_DESC)
            RETURNING EVENT_ID INTO :EVENT_ID
            ";
    
        using (OracleCommand cmd = new OracleCommand(cmdText, oraConn))
        {
            oraConn.Open();
            OracleTransaction trans = oraConn.BeginTransaction();
            try
            {
                OracleParameter prm = new OracleParameter();
                cmd.BindByName = true;
                prm = new OracleParameter("EVENT_NAME", OracleDbType.Varchar2); 
                prm.Value = "SOME NAME"; cmd.Parameters.Add(prm);
    
                prm = new OracleParameter("EVENT_DESC", OracleDbType.Varchar2); 
                prm.Value = "SOME DESC"; cmd.Parameters.Add(prm);
    
                prm = new OracleParameter( "EVENT_ID"
                                         , OracleDbType.Int32
                                         , ParameterDirection.ReturnValue); 
                cmd.Parameters.Add(prm);
    
                cmd.ExecuteNonQuery();
                trans.Commit();
                // return value
                event_id = ConvertFromDB<int>(cmd.Parameters["EVENT_ID"].Value);
            }
            catch
            {
                trans.Rollback();
                throw;
            }
            finally
            {
                trans.Dispose();
            }
            oraConn.Close();
        }
    } 
    

    ConvertFromDB 只是将返回值转换为其 .NET 等效项(在本例中为 int)的泛型。

    希望对您有所帮助。

    编辑:

    您可以在 ODP.NET 中轻松绑定值数组(并检索返回值数组):

    using (OracleConnection oraConn = new OracleConnection(connStr))
    {
        string cmdText = @"insert into TEST_EVENT
            (EVENT_NAME, EVENT_DESC)
            values
            (:EVENT_NAME, :EVENT_DESC)
            RETURNING EVENT_ID INTO :EVENT_ID
            ";
    
        using (OracleCommand cmd = new OracleCommand(cmdText, oraConn))
        {
            oraConn.Open();
            OracleTransaction trans = oraConn.BeginTransaction();
            try
            {
                string[] event_names = new string[2];
                string[] event_descs = new string[2];
                int[] event_ids = new int[2];
    
                event_names[0] = "Event1";
                event_descs[0] = "Desc1";
    
                event_names[1] = "Event2";
                event_descs[1] = "Desc2";
    
                OracleParameter prm = new OracleParameter();
                cmd.Parameters.Clear();
                cmd.ArrayBindCount = 2;
                cmd.BindByName = true;
    
                prm = new OracleParameter("EVENT_NAME", OracleDbType.Varchar2); 
                prm.Value = event_names; cmd.Parameters.Add(prm);
    
                prm = new OracleParameter("EVENT_DESC", OracleDbType.Varchar2); 
                prm.Value = event_descs; cmd.Parameters.Add(prm);
    
                prm = new OracleParameter( "EVENT_ID"
                                         , OracleDbType.Int32
                                         , ParameterDirection.ReturnValue); 
                cmd.Parameters.Add(prm);
    
    
                cmd.ExecuteNonQuery();
                trans.Commit();
                // get return values
    
                event_ids = (int[])(cmd.Parameters["EVENT_ID"].Value);
            }
            catch
            {
                trans.Rollback();
                throw;
            }
            finally
            {
                trans.Dispose();
            }
            oraConn.Close();
        }
    }
    

    【讨论】:

    • 好吧,实际上这并不能回答问题,尽管它很有帮助。问题是如何在 c# 代码中获取在 sql 脚本中声明和初始化的变量(不是参数)的值。但我想问你,1) 你提供的解决方案是否改变了数据库的模式? 2)插入语句是否总是在返回参数中输出id? 3) 在脚本中有两个 INSERT 怎么样?返回哪个id?
    • 另外,没有自动增量策略(序列或其他)的 TABLES 怎么办?在这种情况下,您将如何返回 id? (前提是一切都在事务的上下文中执行)
    • @Saysmaster 请参阅我上面的编辑,以绑定值数组(并获取返回值数组)。至于 id 值,您要么需要在插入语句中提供 ID 值,要么让 Oracle 生成它(通过 trigger/seq 方法)并为您返回。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 2018-09-13
    • 1970-01-01
    • 2017-06-13
    相关资源
    最近更新 更多