Retrieving nested table columns through a REF CURSOR in php
Hello.
I have been able to execute REF CURSORS returned by pl/sql functions succesfully with php. I have also been able to bind collections to the input/output of pl/sql functions/procedures.
However, what I am unable to do, is to execute a cursor returned by a pl/sql function that has one of the columns a named datatype (a simple one-dimensional nested table):
create type stab is table of varchar2(255);
create table lp_landing (
token varchar2(255),
text varchar2(512),
country varchar2(255),
creator varchar2(255),
is_active char(1),
css_file char(1),
autofollowing stab default stab(),
constraint lp_landing_pk primary key (token)) organization index
nested table autofollowing store as lp_landings_af_nt
(constraint autofollowing_pk primary key (nested_table_id,column_value)) organization index compress
function landings_usercountry (in_uname in lp_users.uname%type, in_country in lp_country.cname%type) return Landing_curType
is
ret Landing_curType;
begin
open ret for
select * --token,text,country,creator,is_active,css_file,tab2str(autofollowing) as autofollowing
from lp_landing
where country = (select country
from lp_permissions
where country = in_country and uname = in_uname);
return ret;
end landings_usercountry;
here is the php:
$sql = 'BEGIN :res := LP_PKG.landings_usercountry(:user, :country); END;';
$stmt = oci_parse($c, $sql);
$cursor = oci_new_cursor($c);
oci_bind_by_name($stmt,':user',$name, 32);
oci_bind_by_name($stmt,':country',$country, 32);
oci_bind_by_name($stmt,':res', $cursor, -1, OCI_B_CURSOR);
$name = "root";
$country = "Spain";
try {
@oci_execute($stmt);
$m = oci_error($stmt);
if($m){
throw new Exception($m['message'], $m['code']);
}else{
@oci_execute($cursor);
$m = oci_error($cursor);
if($m){
throw new Exception($m['message'], $m['code']);
}else{
while ( $entry = oci_fetch_object($cursor) ) {
var_dump($entry);
} catch (Exception $e) {
print_r($e);
With "select *" in the function, the autofollowing column (of datatype stab) fails to bind, giving an ORA-932 error. The workaround for the moment is to convert the nested table to a comma delimited string (via the tab2str function).
However, I would like to be able to tell php to accept a collection within the cursor, but I cannot figure out how to do this.
Any ideas?
thx in advance
yes, it is an ORA-932:
Warning: oci_fetch_object() [function.oci-fetch-object]: ORA-00932: inconsistent datatypes: expected CHAR got ADT in /home/apolion/apache2/htdocs/old/test1.php on line 104
Similar Messages
-
Trigger how to get new and old value for nested table column?
Hi,
I have created a nested table based on the following details:
CREATE TYPE typ_item AS OBJECT --create object
(prodid NUMBER(5),
price NUMBER(7,2) )
CREATE TYPE typ_item_nst -- define nested table type
AS TABLE OF typ_item
CREATE TABLE pOrder ( -- create database table
ordid NUMBER(5),
supplier NUMBER(5),
requester NUMBER(4),
ordered DATE,
items typ_item_nst)
NESTED TABLE items STORE AS item_stor_tab
INSERT INTO pOrder
VALUES (800, 80, 8000, sysdate,
typ_item_nst (typ_item (88, 888)));
Now I would like to create a trigger on table pOrder for after insert or update or delete
and I would like to track the new and old value for the columns inside nested table.
Can anybody direct me how to do it?
I would like to know the sytax for it like:
declare
x number;
begin
x := :new.nestedtablecolumn;--how to get the new and old value from nested table columns
end;
Hope my question is clear.
Thanks,
LavanHi,
Try like this:
CREATE OR REPLACE TRIGGER PORDER_I
BEFORE INSERT
ON PORDER
REFERENCING OLD AS old NEW AS new
FOR EACH ROW
DECLARE
items_new typ_item_nst;
ordid_NEW NUMBER;
BEGIN
FOR i IN :new.items.FIRST .. :new.items.LAST LOOP -- For first to last element
DBMS_OUTPUT.PUT_LINE(':new.items(' || I || ').prodid: ' || :new.items(I).prodid );
DBMS_OUTPUT.PUT_LINE(':new.items(' || I || ').price: ' || :new.items(I).price );
END LOOP;
END;Regards,
Peter -
Problem in truncate/drop partitions in a table having nested table columns.
Hi,
I have a table that has 2 columns of type nested table. Now in the purge process, when I try to truncate or drop a partition from this table, I get error that I can't do this (because table has nested tables). Can anybody help me telling how I will be able to truncate/drop partition from this table? IF I change column types from nested table to varray type, will it help?
Also, is there any short method of moving existing data from a nested table column to a varray column (having same fields as nested table)?
Thanks in advance.>
I have a table that has 2 columns of type nested table. Now in the purge process, when I try to truncate or drop a partition from this table, I get error that I can't do this (because table has nested tables). Can anybody help me telling how I will be able to truncate/drop partition from this table?
>
Unfortunately you can't do those operations when a table has a nested table column. No truncate, no drop, no exchange partition at the partition level.
A nested table column is stored as a separate table and acts like a 'child' table with foreign keys to the 'parent' table. It is these 'foreign keys' that prevent the truncation (just like normal foreign keys prevent truncating partions and must be disabled first) but there is no mechanism to 'disable' them.
Just one excellent example (there are many others) of why you should NOT use object columns at all.
>
IF I change column types from nested table to varray type, will it help?
>
Yes but I STRONGLY suggest you take this opportunity to change your data model to a standard relational one and put the 'child' (nested table) data into its own table with a foreign key to the parent. You can create a view on the two tables that can make data appear as if you have a nested table type if you want.
Assuming that you are going to ignore the above advice just create a new VARRAY type and a table with that type as a column. Remember VARRAYs are defined with a maximum size. So the number of nested table records needs to be within the capacity of the VARRAY type for the data to fit.
>
Also, is there any short method of moving existing data from a nested table column to a varray column (having same fields as nested table)?
>
Sure - just CAST the nested table to the VARRAY type. Here is code for a VARRAY type and a new table that shows how to do it.
-- new array type
CREATE OR REPLACE TYPE ARRAY_T AS VARRAY(10) OF VARCHAR2(64)
-- new table using new array type - NOTE there is no nested table storage clause - arrays stored inline
CREATE TABLE partitioned_table_array
( ID_ INT,
arra_col ARRAY_T )
PARTITION BY RANGE (ID_)
( PARTITION p1 VALUES LESS THAN (40)
, PARTITION p2 VALUES LESS THAN(80)
, PARTITION p3 VALUES LESS THAN(100)
-- insert the data from the original table converting the nested table data to the varray type
INSERT INTO PARTITIONED_TABLE_ARRAY
SELECT ID_, CAST(NESTED_COL AS ARRAY_T) FROM PARTITIONED_TABLENaturally since there is no more nested table storage you can truncate or drop partitions in the above table
alter table partitioned_table_array truncate partition p1
alter table partitioned_table_array drop partition p1 -
Nested Table columns and ADF BC 11.1.2
I'm thinking ahead to a new application design, including a new database design. In this application, there are users who may not change the production tables directly, but their changes must be approved (and possibly modified) before they are applied to the production tables. The production tables are part of an existing system, and are fairly well normalized, with a master table and several detail tables.
So for the new design, I want to have a staging table, mirroring the master table, where user changes are stored until they are approved and applied to the production tables. The staging table contains a few extra columns for "add, change or delete", user who submitted the change, date the change was requested. After applying the change, the staging record is to be copied to a change history table, and deleted from staging. That way, the staging table never has a lot of data in it.
Here's the question:
I need to deal with the detail tables. I could have staging versions of each detail table, but I was thinking that it might be easier to handle if the detail tables were included as nested table columns of the master staging table. Most of the detail tables only contain a few rows per master row. But can ADF BC 11.1.2 handle nested table columns? Is it easy to use in an application?Thanks for the quick response. I was thinking I might get a response from someone who had tried it, so I didn't waste time trying it myself. I consider your response is pretty authoritative, and I'll take that as a sign that I should forget the nested tables design.
No, polymorphic views probably won't do the job. I think I'll just go ahead and create staging versions of each detail table with foreign keys back to the master staging table. Then I'll let the wizard create the needed association objects and view links in ADF BC. It will complicate the procedure for applying changes, particularly adding a row to the change history table. But that's the price we'll need to pay.
OTOH - I just had a thought - since the change history table is mostly for auditing, it appears in some reports, but has no CRUD in the application, other than the insert when the changes are applied. If I did that insert with a trigger or some other PL/SQL, then the change history could still be a single table with nested table columns for the details. -
Problem when expanding Tree - Tree with nested table column
Hi, i have created the tree using the Tree with nested table column.
I have created a node called TREE_ROOT in the context.
This node has few attributes which includes children_loaded, is_leaf, is_expanded.
I have created the recursive node TREE_SUB for the above node TREE_ROOT.
In the view, i have created the table with the master column. The above attributes have been mapped accordingly. I have created the action handler for load_children.
In this action handler method, i receive the context_element correctly. In this method, i determine the children of the selected element and the resulting children are attached to this context_element.
But the problem is: when i add elements to context_elements in the method load_children, these
elements get added to the node TREE_ROOT as well.
Please help.
thanks and best regards,
PramodI just use some types defined in this user... Well, I hope you know what is the type definition of d_period_sec,
don't you ? I didn't ask to provide all types existed now, only types you are
using.
Anyhow you have been granted with execute privilege for types you are using:
SQL> conn tau_tll/tau_tll;
Connected.
SQL> create or replace type d_period_sec as object (date# date);
2 /
Type created.
SQL> grant execute on d_period_sec to public with grant option;
Grant succeeded.
SQL> conn scott/tiger
Connected.
SQL> CREATE OR REPLACE TYPE unit_function AS OBJECT (
2 xi NUMBER,
3 yi NUMBER,
4 xe NUMBER,
5 ye NUMBER,
6 xm NUMBER,
7 ym NUMBER,
8 v NUMBER,
9 a NUMBER,
10 f NUMBER,
11 descr VARCHAR2 (20)
12 );
13 /
Type created.
SQL> grant execute on unit_function to master;
Grant succeeded.
SQL> CREATE OR REPLACE TYPE unit_moving_point AS OBJECT
2 (
3 p tau_tll.d_period_sec, -- from user TAU_TLL
4
5 m unit_function
6 )
7 /
Type created.
SQL> grant execute on unit_moving_point to master;
Grant succeeded.
SQL> CREATE OR REPLACE TYPE moving_point_tab AS TABLE OF unit_moving_point;
2 /
Type created.
SQL> grant execute on moving_point_tab to master;
Grant succeeded.
SQL> CREATE OR REPLACE TYPE moving_point AS OBJECT (u_tab moving_point_tab);
2 /
Type created.
SQL> grant execute on moving_point to master;
Grant succeeded.
SQL> conn master/master
Connected.
SQL> CREATE TABLE MPOINTS (
2 id NUMBER,
3 mpoint scott.Moving_Point)
4 NESTED TABLE mpoint.u_tab store as moving_tab;
Table created.Rgds. -
Error deploying Tree By Nesting Table Column
Hi
Im using Tree By Nesting Table Column. When I deploy the application, I get the following exception:
[code]
java.lang.NullPointerException
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TableAdapter$TreeTableRows._initialize(TableAdapter.java:9703)
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.TableAdapter.setViewAndNodeElement(TableAdapter.java:345)
at com.sap.tc.webdynpro.clientserver.uielements.adaptmgr.URAdapterManager.getAdapterFor(URAdapterManager.java:285)
at com.sap.tc.webdynpro.clientserver.uielements.adaptmgr.URAdapterManager.getAdapterFor(URAdapterManager.java:93)
at com.sap.tc.webdynpro.clientserver.uielements.adaptbase.AbstractAdapter.getAdapterFor(AbstractAdapter.java:495)
at com.sap.tc.webdynpro.clientserver.uielib.standard.uradapter.FlowLayoutAdapter$Items.getControl(FlowLayoutAdapter.java:368)
at com.sap.tc.ur.renderer.ie6.FlowLayoutRenderer.renderFlowLayoutItemFragment(FlowLayoutRenderer.java:252)
at com.sap.tc.ur.renderer.ie6.FlowLayoutRenderer.renderFlowLayoutFragment(FlowLayoutRenderer.java:208)
at com.sap.tc.ur.renderer.ie6.FlowLayoutRenderer.render(FlowLayoutRenderer.java:47)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:435)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:134)
at com.sap.tc.ur.renderer.ie6.ScrollContainerRenderer.renderScrollContainerFragment(ScrollContainerRenderer.java:627)
at com.sap.tc.ur.renderer.ie6.ScrollContainerRenderer.render(ScrollContainerRenderer.java:72)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:435)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:134)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.UiWindowRenderer.render(UiWindowRenderer.java:52)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:435)
at com.sap.tc.webdynpro.clientimpl.html.renderer.uielements.base.RenderManager.render(RenderManager.java:134)
at com.sap.tc.webdynpro.clientimpl.html.client.HtmlClient.sendHtml(HtmlClient.java:1025)
at com.sap.tc.webdynpro.clientimpl.html.client.HtmlClient.fillDynamicTemplateContext(HtmlClient.java:455)
at com.sap.tc.webdynpro.clientimpl.html.client.HtmlClient.sendResponse(HtmlClient.java:1172)
at com.sap.tc.webdynpro.clientimpl.html.client.HtmlClient.retrieveData(HtmlClient.java:217)
at com.sap.tc.webdynpro.clientserver.window.WindowPhaseModel.doRetrieveData(WindowPhaseModel.java:595)
at com.sap.tc.webdynpro.clientserver.window.WindowPhaseModel.processRequest(WindowPhaseModel.java:157)
at com.sap.tc.webdynpro.clientserver.window.WebDynproWindow.processRequest(WebDynproWindow.java:344)
at com.sap.tc.webdynpro.clientserver.cal.AbstractClient.executeTasks(AbstractClient.java:143)
at com.sap.tc.webdynpro.clientserver.session.ApplicationSession.doProcessing(ApplicationSession.java:298)
at com.sap.tc.webdynpro.clientserver.session.ClientSession.doApplicationProcessingStandalone(ClientSession.java:705)
at com.sap.tc.webdynpro.clientserver.session.ClientSession.doApplicationProcessing(ClientSession.java:659)
at com.sap.tc.webdynpro.clientserver.session.ClientSession.doProcessing(ClientSession.java:227)
at com.sap.tc.webdynpro.clientserver.session.RequestManager.doProcessing(RequestManager.java:150)
at com.sap.tc.webdynpro.serverimpl.defaultimpl.DispatcherServlet.doContent(DispatcherServlet.java:56)
at com.sap.tc.webdynpro.serverimpl.defaultimpl.DispatcherServlet.doGet(DispatcherServlet.java:40)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.runServlet(HttpHandlerImpl.java:390)
at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.handleRequest(HttpHandlerImpl.java:264)
at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:347)
at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:325)
at com.sap.engine.services.httpserver.server.RequestAnalizer.invokeWebContainer(RequestAnalizer.java:887)
at com.sap.engine.services.httpserver.server.RequestAnalizer.handle(RequestAnalizer.java:241)
at com.sap.engine.services.httpserver.server.Client.handle(Client.java:92)
at com.sap.engine.services.httpserver.server.Processor.request(Processor.java:148)
at com.sap.engine.core.service630.context.cluster.session.ApplicationSessionMessageListener.process(ApplicationSessionMessageListener.java:33)
at com.sap.engine.core.cluster.impl6.session.MessageRunner.run(MessageRunner.java:41)
at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)
at java.security.AccessController.doPrivileged(Native Method)
at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:100)
at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:170)
[/code]
What could be wrong?
Thanks
ojHi
There is no missing value in the property of the MasterColumn element. My context is like this:
Cardinality:0...n, Selection 0...1 for all nodes
HeaderData
|-HeaderID
|-HeaderText
SubnodeData
|-HeaderID
|-SubnodeText
SubNode
|-Children (recursive Node - SubNode)
|-SubnodeText
Expanded (boolean)
Im still getting the error. Im on NW2004s, SP06, using NWDS 7.0.06.
Could there be a problem with the java runtime? if so, what should I do?
Thanks
oj -
How can I iterate over the columns of a REF CURSOR?
I have the following situation:
DECLARE
text VARCHAR2 (100) := '';
TYPE gen_cursor is ref cursor;
c_gen gen_cursor;
CURSOR c_tmp
IS
SELECT *
FROM CROSS_TBL
ORDER BY sn;
BEGIN
FOR tmp IN c_tmp
LOOP
text := 'select * from ' || tmp.table_name || ' where seqnum = ' || tmp.sn;
OPEN c_gen FOR text;
-- here I want to iterate over the columns of c_gen
-- c_gen will have different number of columns every time,
-- because we select from a different table
-- I have more than 500 tables, so I cannot define strong REF CURSOR types!
-- I need something like
l := c_gen.columns.length;
for c in c_gen.columns[1]..c_gen.columns[l]
LOOP
-- do something with the column value
END LOOP;
END LOOP;
END;As you can see from the comments in the code, I couln'd find any examples on the internet with weak REF CURSORS and selecting from many tables.
What I found was:
CREATE PACKAGE admin_data AS
TYPE gencurtyp IS REF CURSOR;
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT);
END admin_data;
CREATE PACKAGE BODY admin_data AS
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
BEGIN
IF choice = 1 THEN
OPEN generic_cv FOR SELECT * FROM employees;
ELSIF choice = 2 THEN
OPEN generic_cv FOR SELECT * FROM departments;
ELSIF choice = 3 THEN
OPEN generic_cv FOR SELECT * FROM jobs;
END IF;
END;
END admin_data;
/But they have only 3 tables here and I have like 500. What can I do here?
Thanks in advance for any help!The issue here is that you don't know your columns at design time (which is generally considered bad design practice anyway).
In 10g or before, you would have to use the DBMS_SQL package to be able to iterate over each of the columns that are parsed from the query... e.g.
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_rowcount NUMBER := 0;
BEGIN
-- create a cursor
c := DBMS_SQL.OPEN_CURSOR;
-- parse the SQL statement into the cursor
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
-- execute the cursor
d := DBMS_SQL.EXECUTE(c);
-- Describe the columns returned by the SQL statement
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
-- Bind local return variables to the various columns based on their types
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Varchar2
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val); -- Number
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val); -- Date
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Any other type return as varchar2
END CASE;
END LOOP;
-- Display what columns are being returned...
DBMS_OUTPUT.PUT_LINE('-- Columns --');
FOR j in 1..col_cnt
LOOP
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
when 2 then 'NUMBER'
when 12 then 'DATE'
else 'Other' end);
END LOOP;
DBMS_OUTPUT.PUT_LINE('-------------');
-- This part outputs the DATA
LOOP
-- Fetch a row of data through the cursor
v_ret := DBMS_SQL.FETCH_ROWS(c);
-- Exit when no more rows
EXIT WHEN v_ret = 0;
v_rowcount := v_rowcount + 1;
DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
DBMS_OUTPUT.PUT_LINE('--------------');
-- Fetch the value of each column from the row
FOR j in 1..col_cnt
LOOP
-- Fetch each column into the correct data type based on the description of the column
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
END CASE;
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------');
END LOOP;
-- Close the cursor now we have finished with it
DBMS_SQL.CLOSE_CURSOR(c);
END;
SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
DEPTNO - NUMBER
SAL - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
DEPTNO : 10
SAL : 2450
Row: 2
EMPNO : 7839
ENAME : KING
DEPTNO : 10
SAL : 5000
Row: 3
EMPNO : 7934
ENAME : MILLER
DEPTNO : 10
SAL : 1300
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
JOB - VARCHAR2
MGR - NUMBER
HIREDATE - DATE
SAL - NUMBER
COMM - NUMBER
DEPTNO - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
JOB : MANAGER
MGR : 7839
HIREDATE : 09/06/1981 00:00:00
SAL : 2450
COMM :
DEPTNO : 10
Row: 2
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
MGR :
HIREDATE : 17/11/1981 00:00:00
SAL : 5000
COMM :
DEPTNO : 10
Row: 3
EMPNO : 7934
ENAME : MILLER
JOB : CLERK
MGR : 7782
HIREDATE : 23/01/1982 00:00:00
SAL : 1300
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from dept where deptno = 10');
-- Columns --
DEPTNO - NUMBER
DNAME - VARCHAR2
LOC - VARCHAR2
Row: 1
DEPTNO : 10
DNAME : ACCOUNTING
LOC : NEW YORK
PL/SQL procedure successfully completed.
SQL>From 11g onwards, you can create your query as a REF_CURSOR, but then you would still have to use the DBMS_SQL package with it's new functions to turn the refcursor into a dbms_sql cursor so that you can then describe the columns in the same way.
http://technology.amis.nl/blog/2332/oracle-11g-describing-a-refcursor
Welcome to the issues that are common when you start to attempt to create dynamic code. If your design isn't specific then your code can't be either and you end up creating more work in the coding whilst reducing the work in the design. ;) -
DB proc - do you need to create a table to pass a ref cursor record type?
I want to pass a limited selection of columns from a large table through a DB procedure using a REF CURSOR, returning a table rowtype:
CREATE OR REPLACE package XXVDF_XPOS_DS021_ITEMS AS
TYPE XXVDF_XPOS_DS021_ITEM_ARRAY
IS REF CURSOR
return XXVDF_XPOS_DS021_ITEM_TABLE%ROWTYPE;
Do I need to create this dummy table?
I can't get a TYPE to work, where the type is an OBJECT with the desired columns in it.
So a dummy empty table will sit in the database...
Is there another way?
thanks!You can use RECORD type declaration:
SQL> declare
2 type rec_type is record (
3 ename emp.ename%type,
4 sal emp.sal%type
5 );
6 type rc is ref cursor return rec_type;
7 rc1 rc;
8 rec1 rec_type;
9 begin
10 open rc1 for select ename, sal from emp;
11 loop
12 fetch rc1 into rec1;
13 exit when rc1%notfound;
14 dbms_output.put_line(rec1.ename || ' ' || rec1.sal);
15 end loop;
16 close rc1;
17 end;
18 /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300or use, for example, VIEW to declare rowtype:
SQL> create view dummy_view as select ename, sal from emp;
View created.
SQL> declare
2 type rc is ref cursor return dummy_view%rowtype;
3 rc1 rc;
4 rec1 dummy_view%rowtype;
5 begin
6 open rc1 for select ename, sal from emp;
7 loop
8 fetch rc1 into rec1;
9 exit when rc1%notfound;
10 dbms_output.put_line(rec1.ename || ' ' || rec1.sal);
11 end loop;
12 close rc1;
13 end;
14 /
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300 Rgds. -
Help on CAST function, defining TYPE TABLE and using a REF cursor
Hi,
I have written a procedure (lookup) inside a package (lookup_pkg) as shown below.
Procedure has an output variable of type PL/SQL TABLE which is defined in the package.
I want to write a wrapper procedure lookupref to the procedure lookup to return a ref cursor.
CREATE OR REPLACE PACKAGE lookup_pkg AS
TYPE t_lookup_refcur IS REF CURSOR;
CURSOR c_lookup IS
Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1;
TYPE t_lookup IS TABLE OF c_lookup%ROWTYPE;
Procedure lookup(id Number, o_lookup OUT t_lookup);
End lookup_pkg;
CREATE OR REPLACE PACKAGE BODY lookup_pkg As
Procedure lookup(id Number, o_lookup OUT t_lookup) IS
BEGIN
END lookup;
Procedure lookupref(id Number, o_lookupref OUT t_lookup_refcur) IS
o_lookup t_lookup;
BEGIN
lookup(id, o_lookup t_lookup);
OPEN t_lookup_refcur FOR
SELECT *
FROM TABLE(CAST(o_lookup AS t_lookup));
Exception
End lookupref;
END lookup_pkg;
When I compile this procedure, I am getting invalid datatype Oracle error and
cursor points the datatype t_lookup in the CAST function.
1. Can anyone tell me what is wrong in this. Can I convert a PL/SQL collection (pl/sql table in this case) to PL/SQL datatype table or does it need to be a SQL datatype only (which is created as a type in database).
Also, to resolve this error, I have created a SQL type and table type instead of PL/SQL table in the package as shown below.
create or replace type t_lookuprec as object
(Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1);
create or replace type t_lookup_tab AS table of t_lookuprec;
CREATE OR REPLACE PACKAGE BODY lookup_pkg As
Procedure lookup(id Number, o_lookup OUT t_lookup) IS
BEGIN
END lookup;
Procedure lookupref(id Number, o_lookupref OUT t_lookup_refcur) IS
o_lookup t_lookup;
BEGIN
lookup(id, o_lookup t_lookup);
OPEN t_lookup_refcur FOR
SELECT *
FROM TABLE(CAST(o_lookup AS t_lookup_tab));
Exception
End lookupref;
END lookup_pkg;
When I compile this package, I am getting "PL/SQL: ORA-22800: invalid user-defined type" Oracle error and
points the datatype t_lookup_tab in the CAST function.
2. Can anyone tell me what is wrong. Can I create a type with a select statement and create a table type using type created earlier?
I have checked the all_types view and found that
value for Incomplete column for these two types are YES.
3. What does that mean?
Any suggestions and help is appreciated.
Thanks
Srinivascreate or replace type t_lookuprec as object
(Select columns1,2,3,....100
FROM A, B, C, D, E
WHERE ROWNUM < 1);You are correct that you need to use CREATE TYPE to use the type in SQL.
However unless I am mistaken you appear to have invented your own syntax for CREATE TYPE, suggest you refer to Oracle documentation. -
Object Modelling Question: How do I create multiple nested table columns in one table
Hi there,
I have a XML doc which is as follows:
<PERSON>
<ADDRESSLIST>
<ADDRESS>111, Hamilton Ave </ADDRESS>
<ADDRESS>222, Cambell Ave </ADDRESS>
</ADDRESSLIST>
<PHONELIST>
<PHONENO>4085551212 </PHONENO>
<PHONENO>6505551212</PHONENO>
</PHONELIST>
</PERSON>
I need a table that looks as follows:
Create table person
(addresslist address_table,
phonelist phone_table
I would like to create a table called person with columns addresslist and phonelist. Each defined as object type table of address and table of phones.
Can anybody please tell me how can I do this.
I have seen that there can only be one nested table per table. If so, how do we do this.
Thanks so much
Pramodpelle.k wrote:
peets wrote:Hehe because it's less typing!
Good one!
Also, it's by far the more dynamic method.
If you want to get pedantic, it's also far less efficient in terms of execution time: each iteration of the loop forks a new process, whereas using a single mkdir command forks only once. The "best" way is the curly-braces method demonstrated above by chimeric. -
Hi,
I've created an enhancement request to allow displayed column headings from ref_cursor output to be copied.
This is still not possible (4.0 EA3)
The ref cursor data can be copied, but not the headings..
See July 2012 discussion of problem in comments at
http://www.thatjeffsmith.com/archive/2011/12/sql-developer-tip-viewing-refcursor-output/Hi,
I think you're out of luck... except if you're on 11g where you can use DBMS_SQL.TO_CURSOR_NUMBER to convert the REF CURSOR to a DBMS_SQL cursor, and then benefit from the DBMS_SQL package to get column details.
http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_sql.htm#CHDJDGDG -
How to fetch less number of columns from a ref cursor
I have a ref cursor which has 10 columns. After "OPEN"ing the ref cursor I want to "FETCH" only 3 columns. When I try that I am getting error. How to achieve that?
Regards.
Shantanu.Supposing your first 3 columns are "stable" in name and type for any SQL statement you use, you can do something like:
SQL> create or replace procedure stable (sql_s in varchar2)
2 is
3 empno emp.empno%type;
4 ename emp.ename%type;
5 a sys_refcursor;
6 begin
7 open a for 'select empno, ename from (' || sql_s ||')';
8 fetch a into empno, ename;
9 while(a%found) loop
10 dbms_output.put_line(ename || '/' || empno);
11 fetch a into empno, ename;
12 end loop;
13 close a;
14 end;
15 /
 
Procedure created.
 
SQL> set serveroutput on;
SQL> exec stable('select * from emp');
SMITH/7369
ALLEN/7499
WARD/7521
JONES/7566
MARTIN/7654
BLAKE/7698
CLARK/7782
SCOTT/7788
KING/7839
TURNER/7844
ADAMS/7876
JAMES/7900
FORD/7902
MILLER/7934
 
PL/SQL procedure successfully completed.
 
SQL> exec stable('select empno, ename, sal from emp');
SMITH/7369
ALLEN/7499
WARD/7521
JONES/7566
MARTIN/7654
BLAKE/7698
CLARK/7782
SCOTT/7788
KING/7839
TURNER/7844
ADAMS/7876
JAMES/7900
FORD/7902
MILLER/7934
 
PL/SQL procedure successfully completed.Rgds. -
How to write lead selection method for a tree by nesting table column
Hi,
I have implemented a table with TreeByNestingTableColumn(To show the tree structure in the table).I am not able to get the selected row element in lead selection method.(I am able to get parent element.) .
could anyone please tell me about this code?
BR,
AshishHi,
Follow the below steps to the solution for your problem
1. Create Action "LeadSelection" in View with parameter (name : 'seletedItem'
and type : I<your node>Element
2. Bind this action to Table property "onLeadSelec"
3. In wdModify()
IWDTable table = (IWDTable) view.getElement("Your table id");
table.mappingOfOnLeadSelect().addSourceMapping("nodeElement", "selectedEle");
4. In onActionLeadSelection()
wdComponentAPI.getMessageManager().reportSuccess("Selected Item : "+selectedEle.get<Your Node Attribute>());
Let me know if you need more clarification
Thanks -
Is it possible to filter the nested table result set of table column
Hi
Create or replace type address_record
as object
( address_no number,
address_name varchar2,
address_startDate date,
address_expiryDate date
create or replace type address_rec_tab
as table of address_record;
Create table employee
(emp_no number,
emp_name varchar2,
adresses address_rec_tab
1st approach
==========
<pre>
select
emp.emp_no,
emp.emp_name,
emp.addresses
from employee emp,
table(*emp.addresses*) add
where add.address_expiryDate >=sysdate
</pre>
In the above example my SQL query address collection object is not returning filtered or current address list.
I suppose this is due to fact taht my where clause is not attached to the nested table.
Through my reading I gather that I can only use the following query to filter the address collection.
2nd approach
==========
<pre>
select
emp.emp_no,
emp.emp_name
cursor(select address_no,
address_name,
address_startDate,
address_expiryDate
from employee emp,
table (*emp.addresses*) add
where add.address_expiry_date >=sysdate)
from employee emp,
table (*emp.addresses*) add
where add.address_expiry_date >=sysdate) -- probably this redundent
</pre>
But this approch forces me to rebuild addresses collection object.
I was wondering anybody can suggest me a way so that 1st approach works? I do not have to rebuild collection object in this way.
Thanks for your help in advance
Regards
CharanCreate statements have been slightly modified;
Create or replace type address_record as object
( address_no number,
address_name varchar2(20),
address_startDate date,
address_expiryDate date
create or replace type address_rec_tab as table of address_record;
Create table employee
(emp_no number,
emp_name varchar2(20),
add_list address_rec_tab
nested table add_list store as a_list
insert into employee values (1, 'KMCHARAN', address_rec_tab ( address_record(1, 'NORTH POLE', trunc(sysdate-1), trunc(sysdate+10) ) ,
address_record(1, 'SOUTH_POLE', trunc(sysdate-1), trunc(sysdate+10) )
insert into employee values (2, 'ME', address_rec_tab ( address_record(2, 'EAST', trunc(sysdate-2), trunc(sysdate+12) ) ,
address_record(2, 'WEST', trunc(sysdate-2), trunc(sysdate+12) )
SQL> l
1 select *
2 from employee
3 ,table(add_list) a
4* where a.Address_StartDate = trunc(sysdate-1)
SQL> /
EMP_NO EMP_NAME
ADD_LIST(ADDRESS_NO, ADDRESS_NAME, ADDRESS_STARTDATE, ADDRESS_EXPIRYDATE)
ADDRESS_NO ADDRESS_NAME ADDRESS_S ADDRESS_E
1 KMCHARAN
ADDRESS_REC_TAB(ADDRESS_RECORD(1, 'NORTH POLE', '08-APR-10', '19-APR-10'), ADDRESS_RECORD(1, 'SOUTH_
1 NORTH POLE 08-APR-10 19-APR-10
1 KMCHARAN
ADDRESS_REC_TAB(ADDRESS_RECORD(1, 'NORTH POLE', '08-APR-10', '19-APR-10'), ADDRESS_RECORD(1, 'SOUTH_
1 SOUTH_POLE 08-APR-10 19-APR-10 -
Pass REF CURSOR to Procedure and LOOP through it
Hi All,
I am trying to figure out how I can pass a ref cursor to a procedure and then loop through it. I have provided an example of what I am attempting to do...just not really sure how to open the ref cursor when it is passed ot the sproc and iterate through it?
Any info would be greatly appreciated.
Version:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
Create Or Replace Package test_ref_pkg
AS
function get_ref_curs
RETURN SYS_REFCURSOR;
procedure process_ref_curs(
p_ref_cursor IN SYS_REFCURSOR
END test_ref_pkg;
Create Or Replace Package Body test_ref_pkg
AS
function get_ref_curs
RETURN SYS_REFCURSOR
IS
l_ref_curs SYS_REFCURSOR;
BEGIN
OPEN l_ref_curs FOR
Select 1 ID, 'Test 1' Name
From DUAL
UNION ALL
Select 2 ID, 'Test 2' Name
From DUAL;
END get_ref_curs;
procedure process_ref_curs(
p_ref_cursor IN SYS_REFCURSOR
IS
BEGIN
---NOT SURE WHAT TO DO TO ITERATE THROUGH THE REF CURSOR I AM PASSING INTO THIS SPROC?----
END process_ref_curs;
END test_ref_pkg;Thanks,
S
Edited by: ScarpacciOne on May 28, 2010 9:11 AM---NOT SURE WHAT TO DO TO ITERATE THROUGH THE REF CURSOR I AM PASSING INTO THIS SPROC?----
-- MAYBE I AM SIMPLE, BUT HOW ABOUT FETCH???
-- if you start to yell, I will yell too!!!!
Sybrand Bakker
Senior Oracle DBA
Maybe you are looking for
-
Need Rep to extrct Opn Sale Ords whch has diff Paymnt terms frm Cust Mast
Hi All, I need code for a Report to extract the Open Sales Orders which has the different Payment Terms from Customer Master .Please help. It's urgent.
-
So I have my ATV hooked up to my tv through the HDMI cable because when I try do it it through my AV Receiver tx-ar608 from ONKYO then there is no picture nor any audio. The receiver works fine with anything else (e.g. bluray player, wii, playstation
-
Iinstall ipod from back up on time machine
Wow, hard to even post a question here! Im getting so frustrated with all of the Apple problems. I've had one defective iMac, one defective Macbook Air, and now it appears that my Time Machine back ups might not be accurate. I've got two iPod Touch[e
-
MacBook Pro 2.0 Upgrades
I use my MBP to run Aperture and will soon be running Logic as well. I am constantly battling hard drive space (I can't even install Logic right now). I currently have a 100gb drive. I want to upgrade. I know I need a SATA drive, and I would like a 7
-
Hello. Sometimes when starting applet I get exceptions during loading: com.sun.deploy.net.FailedDownloadException: Unable to load resource: http://gier.gamepoint.net/games/common-images-lobby_20110907_2_cleaned.jar.pack.gz at com.sun.deploy.net.