views:

1533

answers:

4

I want to batch multiple select statements to reduce round trips to the database. The code looks something like the pseudo code below. It works perfectly on SQL Server, but does not work on Oracle - Oracle complains about the sql syntax. I have had a look around and the only examples I can find of returning multiple result sets from Oracle are using Stored Procedures. Is it possible to do this in Oracle without using Stored Procedures? I am using the MS Oracle data provider, but could use the ODP.Net one if needed.

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  A: 

Hi Stuart, why not use stored procedures instead?

But, if you want to batch them in an inline query, you can use a semicolon (;) to seperate the statements.

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

EDIT: You take a look at this SO question.

EDIT2: Take a look at this answer.

Kirtan
This should work in sql server as well I think
Rune Grimstad
Thanks for your response. I tried putting semi-colons between the statements but had the same problem. I dont want to use stored procs as the sql will be dynamically generated, so will have a variable number of result sets returned. The provided sample is a simplified version of what I am doing.
stuart donald
Doesn't work, you need ref cursors.
tuinstoel
+2  A: 

You should write an anonymous pl/sql block that returns 3 ref cursors.

edit1: Here it is done in an anonymous pl/sql block with one cursor. It should work with three too. Oracle ref cursors don't lock data and they are the fastest way to return a result set from a pl/sql procedure or an anonymous pl/sql bloc.

http://www.oracle.com/technology/oramag/oracle/06-jan/o16odpnet.html

tuinstoel
Hmmm. +1 for the answer.
Kirtan
A: 

How about:

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

An example in C# with multiple cursors and an input parameter:

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();
Daniel Layne