Skip to Main Content
  • Questions
  • How to cancel a query and return a subset of records

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Subhasis.

Asked: December 01, 2015 - 5:47 am UTC

Last updated: December 02, 2015 - 9:19 am UTC

Version: 11g

Viewed 1000+ times

You Asked

I have a requirement like this:
One of the database table can have millions of records. The user gets an UI to search through those records. A java program will be used to fire the queries based on search criteria. In case the search criteria returns a large number of records (lets say a configurable number), is there any way to cancel the query after we know that the query returns a large number of records and ask the user whether to continue with the query or cancel the query? If the user says continue, query execution will continue. Otherwise it will be cancelled and the result found so far will be produced to the user.

Is it possible in Oracle?

Thanks.

Subhasis

and Chris said...

You can cancel a query using the JDBC Statement.cancel method:

https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#cancel( )

This will stop a query before Oracle starts sending results to a client. So you won't have any results "so far". If the query has already finished executing then your code will be fetching the results. In this case you can manually implement a check to stop once you've fetched at least N rows.

What you probably want is a Top-N query however. This will only return up to N rows. This is often more efficient than fetching all the rows because Oracle can optimize the query appropriately.

For more details, read:

http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o17asktom-093877.html

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks for the quick answer.

Subhasis, December 01, 2015 - 10:53 am UTC

Chris,
Thanks for the reply. Actually I was looking for a way where I can see how many records are fetched while the query is being executed. As we are dealing with a large number of records, the requirement is, the user should be able to cancel the query in case they feel that it is taking too much time. While they are waiting, we need to show the count of rows that has been fetched so far. And if they cancel, we need to show them those records that has been fetched so far. I suppose that is not possible, right?
I am assuming that this is not a new question and related to my original question that's why raising it in the review. However if you think it is a new one, I can raise a new one.

Thanks again.

Subhasis

Chris Saxon
December 01, 2015 - 2:00 pm UTC

Until your code starts fetching rows, you don't have any. A query can take a long time to execute yet still return few rows. For example, count(*) on billions of rows will take some time. Yet it only returns one row. If you cancel before the scan is complete Oracle doesn't know the answer, so can't return anything.

As soon as you're in the fetch phase you can stop processing whenever you want (how you do this and show it to the user in your environment is something you'll need to figure out).

I stand by my comment on TopN queries though. It's rare people want or need to see more than 10-20 results at a time. Implementing a Top-N query will do this for you and often result in faster query execution too.

I think this is an appropriate followup to the original question. No need to raise a new one.

pipe row helps?

Ravi, December 01, 2015 - 2:25 pm UTC

I go with top N.

But then basing on the what's asked, looks like pipe row fits the need.

Send the data back to UI with the row number of the record that's being retrieved as well as the number of records selected by the query ( count () over () to get the number of records by the query ) , so when the user cancels he will understand how many he/she has discarded.

Hope this helps
Chris Saxon
December 02, 2015 - 9:19 am UTC

I don't see how this helps. The count still needs to process the entire query before it can show how many there are. So in the billion row example, there's still a delay before there's anything to return to the client.