Oracle ref cursor / normal cursor at schema level - oracle

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;

Related

Creating Oracle Cursor using Java Program

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.

Instance of a type declared within package is opaque after compilation for debug

So i have a type declaration within package as :
TYPE lt_sometpye IS TABLE OF gt_sometype INDEX BY PLS_INTEGER;
and am facing 2 problems :
1st i can create a type in database, not in package, which looks like
TYPE lt_sometpye IS TABLE OF gt_sometype;
but it cant be indexed with INDEX BY PLS_INTEGER which is a requirement.
2nd alternatively i declared same type in the package with index. After compiling it, instances of it are opaque when debugging.
In both cases gt_sometype is also compiled for debug.
How can i make the instance of such type display actual data while being watched during debug?
I'm confused what youre problem is. Why not this?
create or replace type matt_typ AS OBJECT ( a number );
declare
type plsql_type_t is table of matt_typ INDEX BY PLS_INTEGER;
l_tab plsql_type_t;
begin
l_tab (l_tab.count+1) := new matt_typ(5);
end;
Sorry, I know that's not an answer, but the SQL wouldn't fit in a comment.

How to use Oracle Collection of Record type in table?

I was trying to explore Oracle Collection and Record type. How do they work ? I wrote below script, but unable to compile them. What is wrong here ?
create or replace package pkg is
type ty_rec is record(empno emp.empno%type,ename emp.ename%type,sal emp.sal%type);
end pkg;
/
create or replace package body pkg is
end pkg;
/
create or replace type ty_varray is varray(5) of pkg.ty_rec;
/
create or replace type ty_table is table of pkg.ty_rec;
/
create table tab1(
id number,
col_arr ty_varray,
col_tab ty_table
) nested table col_tab store as tab1_col_tab;
/
Also, anyone could explain the Nested Table vs Varray when we are using them in table column. How do they stores data and which one is faster ?
Note: I'm using scott schema, which has default emp table
Records are a PL/SQL construct. This means they cannot be used in pure SQL statements. So you need to create the "record" type as a pure SQL object:
create or replace type ty_emp_rec as object
(empno number
,ename varchar2(20)
,sal number);
/
create or replace type ty_emp_varray is varray(5) of ty_emp_rec;
/
create or replace type ty_emp_table is table of ty_emp_rec;
/
I agree it would be highly neat if your code worked, not least because the ability to define attributes using the %TYPE syntax would be extremely useful. But alas that's restricted to the PL/SQL engine too.
This limitation is down to the ability to declare heap table columns with user-defined types, as your last example shows. Oracle requires its columns to be strongly-typed. The %TYPE syntax would create all sorts of problems here: consider what would happen if emp.empno changed from NUMBER to VARCHAR2, or vice versa.

How can I easily use a collection in an Oracle where clause in a package?

It is my understanding that you cannot use a collection in a where clause unless it is defined at the DB level. I have a distinct dislike for random type definitions laying about a schema. It's a religious thing so don't try to dissuade me.
Types contained within a package are cool, because they are easily found and are related to the work at hand. So having said that I have a package that defines a structure (currently a table type collection) that looks like;
TYPE WORD_LIST_ROW IS RECORD(
WORD VARCHAR(255));
TYPE WORD_LIST IS TABLE OF WORD_LIST_ROW;
There is a routine in the package that instantiates and populates an instance of this. It would be useful to be able to use the instantiated object, or some analog therof in a where clause.
So being the clever (or so I thought) programmer, I said why don't I just create a pipelined function to make a table from the collection which I did, and it looks like;
FUNCTION WORD_LIST_TABLE(IN_WORD_LIST WORD_LIST) RETURN WORD_LIST PIPELINED
AS
OUT_WORD_LIST WORD_LIST := WORD_LIST();
BEGIN
FOR I IN 1 .. IN_WORD_LIST.COUNT
LOOP
PIPE ROW(IN_WORD_LIST(I));
END LOOP;
RETURN;
END WORD_LIST_TABLE;
Then in another routine I call the function that builds the collection, finally I use a pipelined function that uses the collection as input in a cursor's where clause.
sort of like this;
cursor xyz
is
select * from x-stuff where fieldA in (select word from table(word_list_table(temp_word_list));
In the loop for the cursor I get an oracle error ora-21700 object does not exist or is marked for delete.
Is there any easy way to build an oracle object that can be used in an Oracle where clause? Basically what I would like to do is;
select * from whatever where fielda in myobject;
The solution is simple - declare the type at schema level using CREATE TYPE statement and you will be able to use your collections in your SQL statements in PL/SQL blocks.
If you have declared your TYPE inside a PL/SQL package you cannot use it in your queries inside PL/SQL blocks.
Also, you must keep in mind that only varray and nested table type collections can be used in queries as of Oracle 11.2 and you cannot use associative arrays in queries.. In 12c you don't have these restrictions.
For further reference go to Oracle Docs.

What is the difference between "AS" and "IS" in an Oracle stored procedure?

I see Oracle procedures sometimes written with "AS", and sometimes with "IS" keyword.
CREATE OR REPLACE Procedure TESTUSER.KILLINSTANCE (INSTANCEID integer) **AS**
...
vs.
CREATE OR REPLACE Procedure TESTUSER.KILLINSTANCE (INSTANCEID integer) **IS**
...
Is there any difference between the two?
Edit: Apparently, there is no functional difference between the two, but some people follow a convention to use "AS" when the SP is part of a package and "IS" when it is not. Or the other way 'round. Meh.
None whatsover. They are synonyms supplied to make your code more readable:
FUNCTION f IS ...
CREATE VIEW v AS SELECT ...
One minor difference...
They are synonyms for packages and procedures, but not for cursors:
This works...
cursor test_cursor
is
select * from emp;
... but this doesn't:
cursor test_cursor
as
select * from emp;
"IS" and "AS" act as a synonym while creating procedures and packages but not for a cursor, table or view.
Here's another difference (in 10g, at any rate)
Given a loose object type:
CREATE TYPE someRecordType AS OBJECT
(
SomeCol VARCHAR2(12 BYTE)
);
You can create a loose Table type of this object type with either AS or IS
CREATE OR REPLACE TYPE someTableType
IS {or AS} TABLE OF someRecordType;
However, if you create this same table type within a package, you must use IS:
CREATE OR REPLACE PACKAGE SomePackage IS
TYPE packageTableType IS TABLE OF someRecordType;
END SomePackage;
Use of AS in the package yields the following error:
Error(2,30): PLS-00103: Encountered the symbol "TABLE" when expecting one of the following: object opaque
According to TutorialsPoint
The AS keyword is used instead of the IS keyword for creating a
standalone procedure.
and considering previous answers,
I guess
AS is for stand alone (outside of any block, subprogram, package) entities
and
IS is for embedded (within a block, subprogram or package) entities.
.
The AS keyword is used instead of the IS keyword for creating a standalone function.
[ A standalone stored function is a function (a subprogram that returns a single value) that is stored in the database.
Note: A standalone stored function that you create with the CREATE FUNCTION statement is different from a function that you declare and define in a PL/SQL block or package. ]
For more explanation, read this...

Resources