![]() | |
![]() |
| | Thread Tools | Display Modes |
#11
| |||
| |||
|
|
It looks like you want to create a large set of data, so use the pipelined version: Not really. This function will return something between null and 20 |
|
FUNCTION fun_something RETURN some_table_type PIPELINED IS lrec_output some_row_type; BEGIN -- some loop here lrec_output_row := some_row_type(something, somethingelse, somethingmore); PIPE ROW (lrec_output_row); -- end of loop here RETURN; -- note that you return nothing! END; works fine. |
#12
| |||
| |||
|
#13
| |||||||
| |||||||
|
|
Tim X schrieb am 18.06.2011 in <87y610c5ws.fsf (AT) puma (DOT) rapttech.com.au>: If I understand you correctly, I think your approach is flawed. If you are going to select data simply as input to use in a join with data from another query, your better off just doing it all as 1 sql statement. No, because I had within every statement the complex logic of the procedure above. I did not mention but in fact the result set of the stored procedure is to be combined many times with different other tables/views from users, that do not have to understand the logic behind the scene. |
|
The problem with your approach is that you are working hard to circumvent all of Oracle's efforts to make things as optimized as possible. I have to decide whether I prefer some seconds more answering time and a minute to develop the query or a very short answering time and a many hour develop of query for each user. |
|
I know, I could solve my problem by creating a table/temp table as result of my stored procedure. But that is not my question. There are about 10000 records to be processed, this can not so much time that I want to create/drop tables with 5 rows each time I use the procedure. |
|
Consider two simple scenarios. In the first one, you use various SQL statements to extract the final set of data you want. The statements are placed inside a procedure that allows you to both pass various values used to define/control the result set (via bind variables) and set a ref cursor to pass back which you can then query and further process or display the data. Oracle will e able to use any relevant indexes, exploit caching of SQL statements and take full advantage of the optimiser. Now consider your (as I understand it) approach. You want to define procedures that will return a result set whih you then want to use in further queries involving joins and other operations. In this case, you want to effectively generate a pseudo table via a procedure call which you then use in joins and additonal SQL to extract the final result. However, there wil be no indexes, optimiser statistics and little caching opportunities that the DB can use to make things as efficient as possible. I am not absolutely sure, because the result set of the procedure is very small. For this I do not need an index. I know, that oracle likes corresponding indexes in two combined tables but nevertheless I can tell it to use an index for the corresponding table. Something like select /*+ index(B) */ ... from MyResultSet A join AnyOtherTable B on A.B_ID=B.A_ID So I suppose this wouldn't be my problem. There are many ways to solve my problem but there sure is no simple sql I could use. I definitely need program code and definitely have to combine it with other tables. But I would prefer to do it on the server and not on the client. And I prefer to do it without temporary tables. And I do not want to write the same procedure 1000 times for each scenario a user could need. |
|
I also suspect there are other pitfalls with the approach you are adopting. At a guess, I would think you have hit upon this idea because you observed that many of your SQL queries had a common element, making it fairly logical to want to isolate that bit of common SQL in one place - less typing, potentially more maintainable, cleaner code etc. All good objectives to strive for. However, you also need to consider how Oracle processes queries and strive for a balance. This I try. But I can not pass the pitfalls before I know how to return some rows by a PL/SQL stored procedure and use this in a select. |
|
If you are looking at ways to minimise SQl and ensure consistency or make things easier to maintain, maybe look at other Oracle features. For example, rather that your suggestion of a procedure that returns a result set, perhaps a better solution would be to define a materialised view and join with that view to get your final result? Perhaps use functions/procedures that will return a different ref cursor depending on some argument or maybe the whole performance can be improved by using a PL/SQL collection type, which is passed around to different procedures for additional processing so that there is only 1 initial query etc. I think I exactly look for the answer of my question. Materialized views do not work because I probably need 1 View for each row of my table. With collection types I still did not work but I suppose I could not combine it with other tables by select statement. |
|
Tim Thank you Andreas By the way: function MyProc(Param1 in char,Param2 in char...) return MyPackage.MyRefTable; can be compiled but if I use it like Select MyProc('P1','P2') from dual I get the error ora-00902,if Select * from MyProc('P1','P2') I get ora-00933 |
#14
| |||
| |||
|
![]() |
| Thread Tools | |
| Display Modes | |
| |