Creating Oracle Cursor using Java Program - oracle

I wanted to create Oracle Cursor with the help of Java Code. I tried searching on the Internet but I didn't find anything. Can we create Cursor using Java code?

You cannot create a cursor using Java code.
A cursor is a reference (pointer) to a data structure internal to the database representing a query and a corresponding set of results - creating the pointer outside of the database would be meaningless.
From the Oracle Documentation:
Introduction to REF CURSORs
Using REF CURSORs is one of the most powerful, flexible, and scalable ways to return query results from an Oracle Database to a client application.
REF CURSOR is a PL/SQL data type whose value is the memory address of a query work area on the database. In essence, a REF CURSOR is a pointer or a handle to a result set on the database. REF CURSORs are represented through the OracleRefCursor ODP.NET class.
REF CURSORs have the following characteristics:
A REF CURSOR refers to a memory address on the database. Therefore, the client must be connected to the database during the lifetime of the REF CURSOR in order to access it.
A REF CURSOR involves an additional database round-trip. While the REF CURSOR is returned to the client, the actual data is not returned until the client opens the REF CURSOR and requests the data. Note that data is not be retrieved until the user attempts to read it.
A REF CURSOR is not updatable. The result set represented by the REF CURSOR is read-only. You cannot update the database by using a REF CURSOR.
A REF CURSOR is not backward scrollable. The data represented by the REF CURSOR is accessed in a forward-only, serial manner. You cannot position a record pointer inside the REF CURSOR to point to random records in the result set.
A REF CURSOR is a PL/SQL data type. You create and return a REF CURSOR inside a PL/SQL code block.
You need to create a stored procedure (or function) in the database that returns a cursor and then invoke that from your external application.

Related

Oracle ref cursor / normal cursor at schema level

I am wondering if we can declare a cursor or a ref cursor at schema level as stored objects. I tried using the below statement for ref cursor
CREATE TYPE my_ref_cursor IS REF CURSOR RETURNING employees%ROWTYPE;
But I got error. A small working example would do and if we cannot then a brief on reason behind it will be a great help.
I doubt it is possible. From CREATE TYPE Statement:
The CREATE TYPE statement creates or replaces the specification of one of these:
Abstract Data Type (ADT) (including a SQLJ object type)
Standalone varying array (varray) type
Standalone nested table type
Incomplete object type
CREATE OR REPLACE PACKAGE yourSchemaName.yourPackageName AS
TYPE my_ref_cursor IS REF CURSOR RETURN employees%ROWTYPE;
--your stored procedure and function declarations
end yourPackageName ;
This is working example in oracle sql. This is package specification and ref cursor type declaration in it;

Perfomance Out parameter vs Out system ref cursor Oracle Procedure

I have a Procedure in oracle with 12 parameters 4 of them are sys ref cursor. I am replace one cursor from my procedure using 8 more out parameters. Will there be any performance enhancement if use out parameters instead of out ref cursor.
A cursor can be thought of as a pointer to an area of memory within the database that contains a result set - it does not directly contain the results; so when you send a cursor you are just sending the pointer and then whatever user interface you are using will have to make additional round-trips to the database to use that cursor (pointer) to open the result set, fetch rows and then, when you are finished, close the cursor.
When you use an out parameter with individual values then the values can all be returned as the procedure terminates and no additional communication with the database is required.
Will there be any performance enhancement if use out parameters instead of out ref cursor.
So, yes, there may be a performance enhancement if you are returning multiple out parameters rather than a cursor which refers to a result set with a single row. However, as with all performance enhancements, you should profile the changes so that you can see the actual effect (which may be negligible).

Return data rows from a pl/sql block

I want to write pl/sql code which utilizes a Cursor and Bulk Collect to retrieve my data. My database has rows in the order of millions, and sometimes I have to query it to fetch nearly all records on client's request. I do the querying and subsequent processing in batches, so as to not congest the server and show incremental progress to the client. I have seen that digging down for later batches takes considerably more time, which is why I am trying to do it by way of cursor.
Here is what should be simple pl/sql around my main sql query:
declare
cursor device_row_cur
is
select /my_query_details/;
type l_device_rows is table of device_row_cur%rowtype;
out_entries l_device_rows := l_device_rows();
begin
open device_row_cur;
fetch device_row_cur
bulk collect into out_entries
limit 100;
close device_row_cur;
end;
I am doing batches of 100, and fetching them into out_entries. The problem is that this block compiles and executes just fine, but doesn't return the data rows it fetched. I would like it to return those rows just the way a select would. How can this be achieved? Any ideas?
An anonymous block can't return anything. You can assign values to a bind variable, including a collection type or ref cursor, inside the block. But the collection would have to be defined, as well as declared, outside the block. That is, it would have to be a type you can use in plain SQL, not something defined in PL/SQL. At the moment you're using a PL/SQL type that is defined within the block, and a variable that is declared within the block too - so it's out of scope to the client, and wouldn't be a valid type outside it either. (It also doesn't need to be initialised, but that's a minor issue).
Dpending on how it will really be consumed, one option is to use a ref cursor, and you can declare and display that through SQL*Plus or SQL Developer with the variable and print commands. For example:
variable rc sys_refcursor
begin
open :rc for ( select ... /* your cursor statement */ );
end;
/
print rc
You can do something similar from a client application, e.g. have a function returning a ref cursor or a procedure with an out parameter that is a ref cursor, and bind that from the application. Then iterate over the ref cursor as a result set. But the details depend on the language your application is using.
Another option is to have a pipelined function that returns a table type - again defined at SQL level (with create type) not in PL/SQL - which might consume fewer resources than a collection that's returned in one go.
But I'd have to question why you're doing this. You said "digging down for later batches takes considerably more time", which sounds like you're using a paging mechanism in your query, generating a row number and then picking out a range of 100 within that. If your client/application wants to get all the rows then it would be simpler to have a single query execution but fetch the result set in batches.
Unfortunately without any information about the application this is just speculation...
I studied this excellent paper on optimizing pagination:
http://www.inf.unideb.hu/~gabora/pagination/article/Gabor_Andras_pagination_article.pdf
I used technique 6 mainly. It describes how to limit query to fetch page x and onward. For added improvement, you can limit it further to fetch page x alone. If used right, it can bring a performance improvement by a factor of 1000.
Instead of returning custom table rows (which is very hard, if not impossible to interface with Java), I eneded up opening a sys_refcursor in my pl/sql which can be interfaced such as:
OracleCallableStatement stmt = (OracleCallableStatement) connection.prepareCall(sql);
stmt.registerOutParameter(someIndex, OracleTypes.CURSOR);
stmt.execute();
resultSet = stmt.getCursor(idx);

Executing an Oracle stored procedure returning a REF CURSOR using SqlAlchemy

I have a stored procedure that I have defined in Oracle. In that procedure I need to return a recordset. To do this, I am using the SYS_REFCURSOR, which works great inside of Oracle (and with cx_Oracle, for that matter). In my application I am using SqlAlchemy scoped sessions, to support multi-threading.
How can I use the scoped session to return the REF CURSOR? The only way I have been able to get this to work is by declaring an out cursor with the cursor that is active in the session and then executing the stored procedure, like below:
sql = """
BEGIN
example('%s', '%s', '%s', :cur);
END;
""" % (cid, show, type)
conn = sa_tool.session.connection()
in_cur = conn._Connection__connection.cursor()
out_cur = conn._Connection__connection.cursor()
in_cur.execute(sql, cur=out_cur)
results = out_cur.fetchall()
Ideally, I would like to avoid using the connection object in this way, and execute the procedure while letting SqlAlchemy manage the cursors. If that is not possible, is there a reason that the fetch would take so long?
Thanks
I saw this question which was not answered and I decided to jump in. First of all, let me just say that for your scenario there is no better option than SYS_REFCURSOR. Of course, you have alternatives.
An Oracle Cursor is a memory area location where an instruction to execute a SQL statement is stored. A Ref cursor is just a pointer to the cursor location. SYS_REFCURSOR is an specific oracle defined typed of ref cursor. So when you return a SYS_REFCURSOR variable to a client, you are returning a pointer towards the memory location where the instruction to execute the SQL resides. Your client can now execute the instruction using the FETCH operation and get the rows. So this is the best possible way to return a result set to the client.
As an alternative, you might use a PIPELINED FUNCTION, but I can assure you that you won't get any better performance. AskTom has a great explanation about this comparison in this article
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9532870400346178516
Another scenario is whether you want to analyse where the time is consumed, either in the EXECUTE phase or in the FETCH one. If you have a huge time in FETCH, perhaps you might consider transfer the data in another way to the client. If you have a problem in EXECUTION, then you need to make a tuning exercise over your procedure.

Difference between Static Cursor Vs Dynamic Cursor in oracle

Hi Can any body describe, what are the differences between static cursor and dynamic cursor with examples.
•A Static Cursor doesn't reflect data changes made to the DB once the ResultSet has been created whereas a Dynamic Cursor reflects the changes as and when they happen.
•A Static Cursor is much more performant than a Dynamic Cursor as it doesn't require further interaction with the DB server.
•A static cursor supports both Relative and Absolute Positioning whereas a Dynamic Cursor supports only Relative Positioning.
•A Static Cursor can be used for Bookmarking purposes as the data returned is static whereas a Dynamic Cursor can't be used for the same
Static
The complete result set of a static cursor is built in tempdb when the
cursor is opened. A static cursor always displays the result set as it
was when the cursor was opened. Static cursors detect few or no
changes, but consume relatively few resources while scrolling.
Dynamic
Dynamic cursors are the opposite of static cursors. Dynamic cursors
reflect all changes made to the rows in their result set when
scrolling through the cursor. The data values, order, and membership
of the rows in the result set can change on each fetch. All UPDATE,
INSERT, and DELETE statements made by all users are visible through
the cursor.
From
http://technet.microsoft.com/en-us/library/ms191179.aspx
Check ref cursors. For example code, check here. The difference is ofcourse in the ability and implementation.
static cursor refers always one work area associated with cursor.
where as ref cursor refers different work area in memory.
ref cursor is used to declare a cursor with out select statement.

Resources