2009-06-30 8 views
14

Chcę partii wielu instrukcji wyboru, aby zmniejszyć liczbę przejazdów w obie strony do bazy danych. Kod wygląda jak poniższy pseudo kod. Działa doskonale na SQL Server, ale nie działa na Oracle - Oracle skarży się na składnię sql. Rozejrzałem się i jedyne przykłady, jakie mogę znaleźć, zwracając wiele zestawów wyników z Oracle, używają procedur przechowywanych. Czy można to zrobić w Oracle bez używania procedur składowanych? Korzystam z dostawcy danych MS Oracle, ale w razie potrzeby mogę użyć ODP.Net.Batch wielu instrukcji SELECT podczas wywoływania Oracle z ADO.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); 
} 
+0

http://stackoverflow.com/questions/308963/how -to-split-oracle-sql-statement-for-ado-net – Kirtan

+0

Dzięki. Spojrzałem na to, ale jest to nieco inny scenariusz, ponieważ instrukcje SQL nie zwracają żadnych zestawów wyników. –

Odpowiedz

5

Powinieneś napisać anonimowy blok pl/sql, który zwraca 3 kursory ref.

edit1: Tutaj robi się to w anonimowym bloku pl/sql za pomocą jednego kursora. Powinien również działać z trzema. Refkursory Oracle nie blokują danych i są najszybszym sposobem zwrócenia zestawu wyników z procedury pl/sql lub anonimowego bloku pl/sql.

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

+0

Hmmm. +1 za odpowiedź. – Kirtan

+1

Link jest już martwy, ale tutaj jest zarchiwizowana kopia archiwum internetowego: http://web.archive.org/web/20060412173402/http://www.oracle.com/technology/oramag/oracle/06-jan /o16odpnet.html –

+0

Link wydaje się być w okolicach 2017 roku, ale kocham [Wayback Machine] (http://web.archive.org). To uratowało mi szyję przy kilku okazjach. –

0

Dlaczego zamiast tego używać procedur przechowywanych?

Ale jeśli chcesz je wsypać w zapytanie wbudowane, możesz użyć średnika (;), aby oddzielić instrukcje.

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

EDYCJA: Przyjrzyj się this SO question.

EDIT2: Spójrz na this answer.

+0

Powinno to działać również na serwerze sql, myślę, że –

+0

Dziękuję za odpowiedź. Próbowałem wstawiać półkolonie między wypowiedziami, ale miałem ten sam problem. Nie chcę używać przechowywanych proców, ponieważ sql będzie generowany dynamicznie, więc będzie mieć zmienną liczbę zwróconych zestawów wyników. Podana próbka jest uproszczoną wersją tego, co robię. –

+0

Nie działa, potrzebujesz refursorów. – tuinstoel

0

Jak o:

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

Wszystkie kolumny muszą być takie same, ale mogą działać, jeśli są. – vapcguy

9

Przykład w C# z wielu kursorów i parametr wejściowy:

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(); 
+0

Czy możesz mi pomóc w tym http://stackoverflow.com/questions/41306344/how-to-execute-multiple-oracle-query-c-sharp/41308024?noredirect=1#comment69821736_41308024 – sam

+0

Przykładzie Daniela, a także Przykład łącza ODP.Net pokazuje parametry dodawane w tej samej kolejności, w jakiej są widoczne w instrukcji SQL. Jeśli nie są w tej samej kolejności, otrzymasz błąd wskazujący błędną liczbę lub typy argumentów. W większości przypadków nie stanowi to problemu, ale w przypadkach, w których trzeba dodać parametry poza kolejnością, należy ustawić Oracle Bommand BindByName = true; –

Powiązane problemy