【问题标题】:Batch multiple select statements when calling Oracle from ADO.NET从 ADO.NET 调用 Oracle 时批处理多个选择语句
【发布时间】:2010-11-06 22:45:10
【问题描述】:

我想批量处理多个选择语句以减少到数据库的往返次数。该代码类似于下面的伪代码。它在 SQL Server 上完美运行,但在 Oracle 上不起作用 - Oracle 抱怨 sql 语法。我环顾四周,我能找到的从 Oracle 返回多个结果集的唯一示例是使用存储过程。是否可以在不使用存储过程的情况下在 Oracle 中执行此操作?我正在使用 MS Oracle 数据提供程序,但如果需要,可以使用 ODP.Net。

var sql = @"
            select * from table1
            select * from table2
            select * from table3";

DbCommand cmd = GetCommand(sql);
using(var reader = cmd.ExecuteReader())
{
   dt1.Load(reader);
   reader.NextResult();
   dt2.Load(reader);
   reader.NextResult();
   dt3.Load(reader);
}

【问题讨论】:

标签: c# oracle ado.net resultset


【解决方案1】:

您应该编写一个返回 3 个引用游标的匿名 pl/sql 块。

edit1: 这里是在一个带有一个游标的匿名 pl/sql 块中完成的。它也应该与三个一起工作。 Oracle 引用游标不锁定数据,它们是从 pl/sql 过程或匿名 pl/sql 块返回结果集的最快方式。

http://www.oracle.com/technetwork/issue-archive/2006/06-jan/o16odpnet-087852.html

【讨论】:

【解决方案2】:

一个带有多个光标和一个输入参数的 C# 示例:

string ConnectionString = "connectionString";
OracleConnection conn = new OracleConnection(ConnectionString);
StringBuilder sql = new StringBuilder();

sql.Append("begin ");
sql.Append("open :1 for select * from table_1 where id = :id; ");
sql.Append("open :2 for select * from table_2; ");
sql.Append("open :3 for select * from table_3; ");
sql.Append("end;");

OracleCommand comm = new OracleCommand(sql.ToString(),_conn);

comm.Parameters.Add("p_cursor_1", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);

comm.Parameters.Add("p_id", OracleDbType.Int32, Id, ParameterDirection.Input);

comm.Parameters.Add("p_cursor_2", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);

comm.Parameters.Add("p_cursor_3", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);

conn.Open();

OracleDataReader dr = comm.ExecuteReader();

【讨论】:

  • 请你帮我解决这个问题stackoverflow.com/questions/41306344/…
  • Daniel 的示例以及 ODP.Net 链接示例显示了添加参数的顺序与它们在 SQL 语句中看到的顺序相同。如果它们的顺序不同,您将收到一个错误,说明错误的参数数量或类型。在大多数情况下,这不是问题,但在需要乱序添加参数的情况下,请设置 OracleCommand BindByName = true;
【解决方案3】:

为什么不使用存储过程呢?

但是,如果您想在内联查询中对它们进行批处理,可以使用分号 (;) 分隔语句。

var sql = @"BEGIN
                select * from table1;
                select * from table2;
                select * from table3;
            END;";

编辑:你看看this SO question

EDIT2:看看this answer

【讨论】:

  • 感谢您的回复。我尝试在语句之间加上分号,但遇到了同样的问题。我不想使用存储过程,因为 sql 将是动态生成的,因此会返回可变数量的结果集。提供的示例是我所做工作的简化版本。
【解决方案4】:

怎么样:

var sql = @"
            select * from table1 UNION
            select * from table2 UNION
            select * from table3";

【讨论】:

  • 所有列都必须相同,但如果它们相同也可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多