Пакетные команды множественного выбора при вызове Oracle из ADO.NET
Я хочу, чтобы пакет нескольких операторов выбора сокращал круглые поездки в базу данных. Код выглядит примерно как псевдо-код ниже. Он отлично работает на 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);
}
Ответы
Ответ 1
Вы должны написать анонимный блок pl/sql, который возвращает 3 курсора ref.
edit1: Здесь это делается в анонимном блоке pl/sql с одним курсором. Он должен работать и с тремя. Курсоры Oracle ref не блокируют данные, и это самый быстрый способ вернуть результирующий набор из процедуры pl/sql или анонимного блока pl/sql.
http://www.oracle.com/technetwork/issue-archive/2006/06-jan/o16odpnet-087852.html
Ответ 2
Пример в С# с несколькими курсорами и входным параметром:
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();
Ответ 3
почему бы не использовать хранимые процедуры вместо этого?
Но, если вы хотите выполнить их в встроенном запросе, вы можете использовать точку с запятой (;) для разделения операторов.
var sql = @"BEGIN
select * from table1;
select * from table2;
select * from table3;
END;";
EDIT: посмотрите этот вопрос SO.
EDIT2: посмотрите этот ответ.
Ответ 4
Как насчет:
var sql = @"
select * from table1 UNION
select * from table2 UNION
select * from table3";