Pipelined function in package example 11g
Hi all,
could you please show me example of using pipelined function in package with my sample data?
My need is to return the following data using pipelined function in package:
select 1 as t, 2 as y, 'u' as j, trunc(sysdate-1) as k from dual union all
select 3 as t, 4 as y, 'h' as j, trunc(sysdate-2) as k from dual Thanks ahead.
p.s. if your problem is that you're not sure how to pipe multiple columns, take a look at this example (from my library of standard examples)...
SQL> CREATE OR REPLACE TYPE myemp AS OBJECT
2 ( empno number,
3 ename varchar2(10),
4 job varchar2(10),
5 mgr number,
6 hiredate date,
7 sal number,
8 comm number,
9 deptno number
10 )
11 /
Type created.
SQL> CREATE OR REPLACE TYPE myrectable AS TABLE OF myemp
2 /
Type created.
SQL> CREATE OR REPLACE FUNCTION pipedata(p_min_row number, p_max_row number) RETURN myrectable PIPELINED IS
2 v_obj myemp := myemp(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
3 BEGIN
4 FOR e IN (select *
5 from (
6 select e.*
7 ,rownum rn
8 from (select * from emp order by empno) e
9 )
10 where rn between p_min_row and p_max_row)
11 LOOP
12 v_obj.empno := e.empno;
13 v_obj.ename := e.ename;
14 v_obj.job := e.job;
15 v_obj.mgr := e.mgr;
16 v_obj.hiredate := e.hiredate;
17 v_obj.sal := e.sal;
18 v_obj.comm := e.comm;
19 v_obj.deptno := e.deptno;
20 PIPE ROW (v_obj);
21 END LOOP;
22 RETURN;
23 END;
24 /
Function created.
SQL> select * from table(pipedata(1,5));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-1980 00:00:00 800 20
7499 ALLEN SALESMAN 7698 20-FEB-1981 00:00:00 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-1981 00:00:00 1250 500 30
7566 JONES MANAGER 7839 02-APR-1981 00:00:00 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-1981 00:00:00 1250 1400 30
SQL> select * from table(pipedata(6,10));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7698 BLAKE MANAGER 7839 01-MAY-1981 00:00:00 2850 30
7782 CLARK MANAGER 7839 09-JUN-1981 00:00:00 2450 10
7788 SCOTT ANALYST 7566 19-APR-1987 00:00:00 3000 20
7839 KING PRESIDENT 17-NOV-1981 00:00:00 5000 10
7844 TURNER SALESMAN 7698 08-SEP-1981 00:00:00 1500 0 30
SQL> select * from table(pipedata(11,15));
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7876 ADAMS CLERK 7788 23-MAY-1987 00:00:00 1100 20
7900 JAMES CLERK 7698 03-DEC-1981 00:00:00 950 30
7902 FORD ANALYST 7566 03-DEC-1981 00:00:00 3000 20
7934 MILLER CLERK 7782 23-JAN-1982 00:00:00 1300 10
SQL>
Similar Messages
-
Pass multiple values as single input parameter into pipelined function
Hi all,
My need is to pass multiple values as single input parameter into pipelined function.
For example - "2" and "3" are values of input parameter "t":
with data as (
select 1 as t from dual union all
select 2 as t from dual union all
select 3 as t from dual union all
select 4 as t from dual union all
select 5 as t from dual
select * from data where t in (2,3)Is it possible at all?Not exactly sure, but usually 'multiple values'+'pipelined function' = some IN-LIST related approach?
See:
SQL> create table data as
2 select 1 as t from dual union all
3 select 2 as t from dual union all
4 select 3 as t from dual union all
5 select 4 as t from dual union all
6 select 5 as t from dual;
Table created.
SQL> --
SQL> CREATE OR REPLACE FUNCTION in_list (p_in_list IN VARCHAR2)
2 RETURN sys.odcivarchar2list PIPELINED
3 AS
4 l_text VARCHAR2(32767) := p_in_list || ',';
5 l_idx NUMBER;
6 BEGIN
7 LOOP
8 l_idx := INSTR(l_text, ',');
9 EXIT WHEN NVL(l_idx, 0) = 0;
10 PIPE ROW (TRIM(SUBSTR(l_text, 1, l_idx - 1)));
11 l_text := SUBSTR(l_text, l_idx + 1);
12 END LOOP;
13
14 RETURN;
15 END;
16 /
Function created.
SQL> --
SQL> select *
2 from data
3 where t in ( select *
4 from table(in_list('1,2'))
5 );
T
1
2
2 rows selected.http://www.oracle-base.com/articles/misc/dynamic-in-lists.php
or
http://tkyte.blogspot.nl/2006/06/varying-in-lists.html -
Hi!
I have a problem with List View Report in mobile application (theme 50 in apex) after updating to apex 4.2.2. I created Report -> List View. I used select from pipelined function in Region Source. Then when page is running and submited three times (or refreshed three times) I get an error:
Error during rendering of region "LIST VIEW".
ORA-01007: variable not in select list
Technical Info (only visible for developers)
is_internal_error: true
apex_error_code: APEX.REGION.UNHANDLED_ERROR
ora_sqlcode: -1007
ora_sqlerrm: ORA-01007: variable not in select list
component.type: APEX_APPLICATION_PAGE_REGIONS
component.id: 21230833903737364557
component.name: LIST VIEW
error_backtrace:
ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 4613
ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 3220
I get this error only when I use select from pipelined function in Region Source (for example: "select value1, value2 from table(some_pipelined_function(param1, param2)) ").
You can check it on http://apex.oracle.com/pls/apex/f?p=50591 (login - demo, password - demo).
In this application:
- I created package TAB_TYPES_PKG:
create or replace PACKAGE TAB_TYPES_PKG IS
TYPE cur_rest_r IS RECORD (
STR_NAME VARCHAR2(128),
INFO VARCHAR2(128)
TYPE cur_rest_t IS TABLE OF cur_rest_r;
END TAB_TYPES_PKG;
- I created pipelined function TEST_FUNC:
create or replace
FUNCTION TEST_FUNC
RETURN TAB_TYPES_PKG.cur_rest_t PIPELINED IS
r_cur_rest TAB_TYPES_PKG.cur_rest_r;
BEGIN
r_cur_rest.STR_NAME := 'ROW 1';
r_cur_rest.INFO := '10';
PIPE ROW (r_cur_rest);
r_cur_rest.STR_NAME := 'ROW 2';
r_cur_rest.INFO := '20';
PIPE ROW (r_cur_rest);
r_cur_rest.STR_NAME := 'ROW 3';
r_cur_rest.INFO := '30';
PIPE ROW (r_cur_rest);
r_cur_rest.STR_NAME := 'ROW 4';
r_cur_rest.INFO := '40';
PIPE ROW (r_cur_rest);
r_cur_rest.STR_NAME := 'ROW 5';
r_cur_rest.INFO := '50';
PIPE ROW (r_cur_rest);
RETURN;
END TEST_FUNC;
- I created List View Report on Page 1:
Region Source:
SELECT str_name,
info
FROM TABLE (TEST_FUNC)
We can see error ORA-01007 after refresing (or submiting) Page 1 three times or more.
How to fix it?Hi all
I'm experiencing the same issue. Predictably on every third refresh I receive:
Error
Error during rendering of region "Results".
ORA-01007: variable not in select list
Technical Info (only visible for developers)
is_internal_error: true
apex_error_code: APEX.REGION.UNHANDLED_ERROR
ora_sqlcode: -1007
ora_sqlerrm: ORA-01007: variable not in select list
component.type: APEX_APPLICATION_PAGE_REGIONS
component.id: 6910805644140264
component.name: Results
error_backtrace: ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 4613 ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 3220
OK
I am running Application Express 4.2.2.00.11 on GlassFish 4 using Apex Listener 2.0.3.221.10.13.
Please note: this works perfectly using a classic report in my desktop application; however, no joy on the mobile side with a list view. I will use a classic report in the interim.
My region source is as follows:
SELECT description AS "DESCRIPTION", reference AS "REFERENCE" FROM TABLE(AUTOCOMPLETE_LIST_VIEW_FNC('RESULTS'))
The procedure:
FUNCTION AUTOCOMPLETE_LIST_VIEW_FNC(
p_collection_name IN VARCHAR2)
RETURN list_row_table_type
AS
v_tab list_row_table_type := list_row_table_type();
BEGIN
DECLARE
jsonarray json_list;
jsonobj json;
json_clob CLOB;
BEGIN
SELECT clob001
INTO json_clob
FROM apex_collections
WHERE collection_name = p_collection_name;
jsonobj := json(json_clob);
jsonarray := json_ext.get_json_list(jsonobj, 'predictions');
FOR i IN 1..jsonArray.count
LOOP
jsonobj := json(jsonArray.get(i));
v_tab.extend;
v_tab(v_tab.LAST) := list_row_type(json_ext.get_string(jsonobj, 'description'), json_ext.get_string(jsonobj, 'reference'));
END LOOP;
RETURN(v_tab);
END;
END AUTOCOMPLETE_LIST_VIEW_FNC;
Thanks!
Tim -
How do you pass parameters to a Pipelined function?
I am using Oracle 10G and the ODP .NET 32 bit client.
I am facing an issue trying to use variable binding with a pipeline function in Oracle. I am using ODP .NET for connecting to the database.
If you want to be familiar with PIPELINED functions, you can read [this blog.|http://oradim.blogspot.com/2007/10/odpnet-tip-using-pipelined-functions.html]
I have very similar code with a difference. My function takes in two parameters that I need to pass to get the table. This is working in SQLPLUS without any issues.
In my C# code, however things change. My function no longer returns a recordset (data reader), if I use the standard method of assigning the parameters.
The code will work if I concat the variables in a string.
Here is the example that doesn't work.
static OracleDataReader fetchData(OracleConnection oc, string strPONumber)
try
OracleCommand od = oc.CreateCommand();
od.CommandType = System.Data.CommandType.Text;
od.CommandText = "select * from table(pkg_fetchPOInfo.getPORowsTable(:1,:2))";
OracleParameter op1 = new OracleParameter();
op1.ParameterName = "1";
op1.OracleDbType = OracleDbType.Varchar2;
op1.Direction = System.Data.ParameterDirection.Input;
op1.Size = 7;
op1.Value = strPONumber;
od.Parameters.Add(op1);
OracleParameter op2 = new OracleParameter();
op2.ParameterName = "2";
op2.OracleDbType = OracleDbType.Varchar2;
op2.Direction = System.Data.ParameterDirection.Input;
op2.Size = 3;
op2.Value = "US";
od.Parameters.Add(op2);
OracleDataReader or = od.ExecuteReader();
return or;
catch (Exception e)
Console.WriteLine("Error " + e.ToString());
return null;
}Here is the example that does.
static OracleDataReader fetchData(OracleConnection oc, string strPONumber)
try
OracleCommand od = oc.CreateCommand();
string formSQL = "Select * from table(pkg_fetchPOInfo.getPORowsTable('"+strPONumber+"','US'))";
od.CommandType = System.Data.CommandType.Text;
od.CommandText = formSQL;
OracleDataReader or = od.ExecuteReader();
return or;
catch (Exception e)
Console.WriteLine("Error " + e.ToString());
return null;
}throw it into an anonymous block and it should work for you.
--create or replace type varcharTableType as table of varchar2 (4000);
create or replace
PACKAGE TESTP AS
function TESTPIPE(nr in number, nr2 in number) return varchartabletype pipelined;
END TESTP;
CREATE OR REPLACE
PACKAGE BODY TESTP AS
function TESTPIPE(nr in number, nr2 in number) return varchartabletype pipelined AS
CURSOR TESTPIPE_cur
IS
SELECT (level + 1) datam
FROM dual
connect by level < nr;
vtt varchartabletype ;
BEGIN
OPEN TESTPIPE_cur;
LOOP
FETCH testpipe_cur
BULK COLLECT INTO vtt LIMIT nr2;
FOR indx IN 1 .. vtt.COUNT
LOOP
Pipe Row ( vtt( indx ) ) ;
END LOOP;
EXIT WHEN testpipe_cur%NOTFOUND;
END LOOP;
END TESTPIPE;
END TESTP;
public static void pipeTest()
String conString = GetConnectionString();
OracleConnection _conn = new OracleConnection(conString);
_conn.Open();
OracleCommand oCmd = new OracleCommand();
oCmd.CommandText = "begin open :crs for Select * from table(testp.testpipe(:nr,:nr2)); end;";
oCmd.CommandType = CommandType.Text ;
oCmd.Connection = _conn;
OracleParameter crs = new OracleParameter();
crs.OracleDbType = OracleDbType.RefCursor;
crs.Direction = ParameterDirection.Output;
crs.ParameterName = "crs";
oCmd.Parameters.Add(crs);
OracleParameter nr = new OracleParameter();
nr.OracleDbType = OracleDbType.Int64;
nr.Direction = ParameterDirection.Input ;
nr.ParameterName = "nr";
nr.Value = 25;
oCmd.Parameters.Add(nr);
OracleParameter nr2 = new OracleParameter();
nr2.OracleDbType = OracleDbType.Int64;
nr2.Direction = ParameterDirection.Input;
nr2.ParameterName = "nr2";
nr2.Value = 10;
oCmd.Parameters.Add(nr2);
using (OracleDataReader MyReader = oCmd.ExecuteReader())
int ColumnCount = MyReader.FieldCount;
// get the data and add the row
while (MyReader.Read())
String s = MyReader.GetOracleValue(0).ToString();
Console.WriteLine(string.Format("i={0}", s));
Console.ReadLine();
} -
How to find Unused variables in procedure,function or package
Hi all,
I want find out unused variables in procedure, function and package.
I have written below script for doing this ,but i am not getting the expected result.
Kindly help me to improve the below code ,so that it works as expected.
{code}
version details
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
"CORE 11.2.0.3.0 Production"
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
{code}
{code}
What i Have tried is This.
DECLARE
V_OBJECT_NAME VARCHAR2(30) :='PR_PRINT';
V_OBJECT_TYPE VARCHAR2(30) :='PROCEDURE';
CURSOR C1(CP_OBJECT_NAME VARCHAR2,CP_OBJECT_TYPE VARCHAR2)
IS
SELECT US.NAME,
US.TYPE,
US.LINE,
REGEXP_SUBSTR(US.TEXT,'.* ') AS var_name
FROM user_source US
WHERE name=CP_OBJECT_NAME
AND type =CP_OBJECT_TYPE
AND REGEXP_LIKE (TEXT,'(v_|g_|c_)','i')
AND REGEXP_LIKE (TEXT,'^[^ ]')
AND REGEXP_LIKE (TEXT,'^[^--]') ;
v_count NUMBER ;
BEGIN
FOR i IN C1(V_OBJECT_NAME,V_OBJECT_TYPE)
LOOP
SELECT COUNT( *)
INTO V_COUNT
FROM USER_SOURCE US
WHERE US.NAME=I.NAME
AND REGEXP_LIKE(US.TEXT,i.var_name,'i' )
AND US.LINE<>I.LINE;
IF V_COUNT =0 THEN
DBMS_OUTPUT.PUT_LINE('variable '||I.VAR_NAME||'Is declared at line#'||I.LINE||' But no where used');
END IF ;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('p_err_code := '||SQLCODE||dbms_utility.format_Error_backtrace());
DBMS_OUTPUT.PUT_LINE('p_err_msg := '||sqlerrm);
END ;
{code}
Thanks,
P PrakashHello,
as suggested by padders you can use PL/Scope, an example:
ALTER SESSION SET PLSCOPE_SETTINGS='IDENTIFIERS:ALL';
CREATE OR REPLACE PACKAGE ui_test1 AS
global_number NUMBER := 9;
FUNCTION get_number
RETURN NUMBER;
END ui_test1;
CREATE OR REPLACE PACKAGE BODY ui_test1 AS
PROCEDURE setNull
p_varchar IN OUT VARCHAR2
IS
BEGIN
p_varchar := NVL(p_varchar,'NULL');
END setNull;
FUNCTION get_number
RETURN NUMBER
IS
FUNCTION setZero
p_number IN NUMBER
RETURN NUMBER
IS
BEGIN
RETURN NVL(p_number,0);
END setZero;
BEGIN
RETURN global_number;
END get_number;
END ui_test1;
SELECT DISTINCT
object_name
,object_type
,name
,type
,line
,col
FROM all_identifiers obj
WHERE obj.owner = USER
AND obj.usage = 'DECLARATION'
AND obj.object_name = 'UI_TEST1'
AND NOT EXISTS (
SELECT 1
FROM all_identifiers with_rh
WHERE obj.signature = with_rh.signature
AND with_rh.usage IN ('REFERENCE','CALL','ASSIGNMENT')
ORDER BY TYPE
,object_name
,object_type
,name;
OBJECT_NAME OBJECT_TYPE NAME TYPE LINE COL
UI_TEST1 PACKAGE GET_NUMBER FUNCTION 11 10
UI_TEST1 PACKAGE BODY SETZERO FUNCTION 35 14
UI_TEST1 PACKAGE UI_TEST1 PACKAGE 1 9
UI_TEST1 PACKAGE BODY SETNULL PROCEDURE 12 11
Regards
Marcus -
Record vs object vs globle table in pipelined function
i want to make pipeline function , i show it can be made in following ways
please suggest which one is better in performance and maintenance.
1)
create type my_tab_type is object
(prodid number, a varchar2(1), b varchar2(1),
c varchar2(1), d varchar2(1), e varchar2(1))
create type my_tab_type_coll is table of my_tab_type;
create or replace function get_some_data (p_val in number)
return my_tab_type_coll pipelined is
begin
FOR i in (select * from my_table where prodid=p_val) loop
pipe row(my_tab_type(i.prodid,i.a,i.b,i.c,i.d,i.e));
end loop;
return;
end;
SELECT * FROM table(get_Some_Data(3));
2)
one can create globle tem table "Tlb_3". then can make a package like fllowing
create or replace
PACKAGE pk1
AS
TYPE T_type IS TABLE OF Tlb_3%ROWTYPE;
END;
and rest of the thing will be same like first one.
3)
TYPE outrec_typ IS RECORD (
var_num NUMBER(6),
var_char1 VARCHAR2(30),
var_char2 VARCHAR2(30)
TYPE outrecset IS TABLE OF outrec_typ;
and rest of the thing will be same like first one
so main question is relating to declaretion of TABLE which is returned.
yours sincerely
Edited by: 944768 on Jan 2, 2013 4:23 AMDUPLICATE THREAD!
How many times do you intend to ask this question?
This is the same question that you ask, and got answered, six months ago in this thread?
how to write Function returing table or set of rows.
And you ask it again a week ago in this thread
object vs record in pipelined function.
Have you forgotten those answers already? Why didn't you take the advice given there and perform some tests?
And you don't seem to acknowledge any of the help you get to your questions by marking them ANSWERED when they have been.
Please revisit this 32 questions and mark them ANSWERED as appropriate - Total Questions: 73 (32 unresolved)
>
i want to make pipeline function , i show it can be made in following ways
please suggest which one is better in performance and maintenance.
>
Why didn't you take the advice given there and perform some tests?
Option #1, using SQL types is better, especially for maintenance. Also SQL types are required if the function is going to be called from SQL. You can define PL/SQL or %ROWTYPE package variables and use them but Oracle will silently create 'hidden' (in 11g) SQL types and use those.
See Solomon's explanation and sample code in this recent thread
Re: Pipe line function
There certainly isn't any need to create a global temp table just so you can create the %ROWTYPE variable; you can create one of those based on a CURSOR. -
Pipeline functions - what happens under the hood? (10g)
Hi all,
What happens when you call a pipelined function? (As opposed to a plain table-valued function.)
From what I understand, a pipelined function will return rows as they are needed. Let's say I have a really silly example of a pipelined function,
CREATE OR REPLACE PACKAGE BODY TEST_PACKAGE_1
AS
FUNCTION GET_DATA RETURN JUST_A_TABLE PIPELINED
IS
BEGIN
PIPE ROW (JUST_A_TYPE('HELLO'));
PIPE ROW (JUST_A_TYPE('WORLD'));
RETURN;
END;
END TEST_PACKAGE_1;
/Then let's say I were to SELECT * FROM TABLE(TEST_PACKAGE_1.GET_DATA) WHERE ROWNUM = 1, what happens to the second row? Does the code that returns the second row still get educated? (Obviously it's omitted from the query, but does it still get generated somewhere and just go nowhere?)
If I have a cursor on a PL/SQL block that selects from GET_DATA, will each row only be returned as the cursor references it? In that case, what happens to the rows that don't get selected? If there some resource that need to be closed out (say, just before the return statement), would it still be safe to close it out?
Thanks!
DonInteresting question, lets try a simple test and see we'll just take your example function and toss in a few dbms_output statements like so:
CREATE OR REPLACE PACKAGE BODY TEST_PACKAGE_1
AS
FUNCTION GET_DATA RETURN JUST_A_TABLE PIPELINED
IS
BEGIN
dbms_output.put_line('ONE');
PIPE ROW (JUST_A_TYPE('HELLO'));
dbms_output.put_line('TWO');
PIPE ROW (JUST_A_TYPE('WORLD'));
dbms_output.put_line('THREE');
RETURN;
END;
END TEST_PACKAGE_1;Now not forgetting to enable dbms_output call it three times like so:
SELECT * FROM TABLE(TEST_PACKAGE_1.GET_DATA) WHERE ROWNUM = 1;
SELECT * FROM TABLE(TEST_PACKAGE_1.GET_DATA) WHERE ROWNUM <= 2;
SELECT * FROM TABLE(TEST_PACKAGE_1.GET_DATA) WHERE ROWNUM <= 3;What I saw from my test was that with the first call I got 1 row of data from the pipelined function and only the first dbms_output statement was processed. For the second statement I got 2 rows of data from the function and the first two dbms_output statements were processed. For the final call I again got 2 rows of data from the function and all 3 dbms_output statements were processed.
My environment:
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Product
PL/SQL Release 10.2.0.1.0 - Production
"CORE 10.2.0.1.0 Production"
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production -
Select remote pipelined function
System: AIX 5.1L
Oracle: 9.2.0.5.0 64 Bit
If I have a package, created in schema 'exceed', on 1 instance which has a pipelined function. I then grant execute to this package for another user, called 'nav'. On another instance, that has a database link (testtrjo) to the instance with the package above using the 'nav' user account to connect, I get error: ORA-30626: function/procedure parameters of remote object types are not supported. Here is is how I am executing this table funtion across the link:
select * from table(exceed.UP_EXCEED.UF_GetOpenEvent@testtrjo('locationsexport'));
When I execute this function as the 'nav' user on the instance that contains the package, it works fine. Like this:
select * from table(exceed.UP_EXCEED.UF_GetOpenEvent('locationsexport'));
Anyone know why this is happening? In the Oracle docs it states:
"Syntax for SQL Calling a PL/SQL Function
Use the following syntax to reference a PL/SQL function from SQL:
[[schema.]package.]function_name[@dblink][(param_1...param_n)]
For example, to reference a function you created that is called My_func, in the
My_funcs_pkg package, in the Scott schema, that takes two numeric parameters,
you could call the following:
SELECT Scott.My_funcs_pkg.My_func(10,20) FROM dual;"
Any help would be appreciated.Thanks for the reply. I did see that before I posted and tried it also but here is what happens:
create synonym Trjo_Exceed for UP_EXCEED@TestTrjo;
select * from table(Trjo_Exceed.UF_GetOpenEvent('locationsexport'));
ORA-00904: "TRJO_EXCEED"."UF_GETOPENEVENT": invalid identifier -
Pipelined function in reports6i....1
Hi,
i have a problem with using pipelined function in
reports6i.
can i use pipelined function in reports6i.
The following code is used to return rows
based on the parameter i am passing:
my package declaration and body is as follows:
PACKAGE P_RET_ARRAY IS
TYPE array1 AS TABLE OF NUMBER;
FUNCTION ret_array(str VARCHAR2)
RETURN ARRAY1 PIPELINED;
END;
PACKAGE BODY P_RET_ARRAY IS
FUNCTION ret_array(str VARCHAR2)
RETURN ARRAY1 pipelined
IS
str1 VARCHAR2(100);
num1 NUMBER(5);
BEGIN
str1 := str ||',';
WHILE LENGTH(str1)>=0
LOOP
num1 := TO_NUMBER(SUBSTR(str1,1,INSTR(str1,',',1)-1));
pipe (num1);
str1 := SUBSTR(str1,INSTR(str1,',',1)+1);
END LOOP;
--NULL;
RETURN ;
END;
END;
I got the above piece of code from one of the oracle forums:
now if i am trying to use this code in my reports6i it's not recognizing
pipelined.any suggestions plz .
it's urgent....Hi,
i have a problem with using pipelined function in
reports6i.
can i use pipelined function in reports6i.
The following code is used to return rows
based on the parameter i am passing:
my package declaration and body is as follows:
PACKAGE P_RET_ARRAY IS
TYPE array1 AS TABLE OF NUMBER;
FUNCTION ret_array(str VARCHAR2)
RETURN ARRAY1 PIPELINED;
END;
PACKAGE BODY P_RET_ARRAY IS
FUNCTION ret_array(str VARCHAR2)
RETURN ARRAY1 pipelined
IS
str1 VARCHAR2(100);
num1 NUMBER(5);
BEGIN
str1 := str ||',';
WHILE LENGTH(str1)>=0
LOOP
num1 := TO_NUMBER(SUBSTR(str1,1,INSTR(str1,',',1)-1));
pipe (num1);
str1 := SUBSTR(str1,INSTR(str1,',',1)+1);
END LOOP;
--NULL;
RETURN ;
END;
END;
I got the above piece of code from one of the oracle forums:
now if i am trying to use this code in my reports6i it's not recognizing
pipelined.any suggestions plz .
it's urgent.... -
ORA-22905 with pipelined function
Hi,
I have a strange behaviour that I do not understand.
The code below does not work. It gives me the following errors:
ORA-22905: cannot access rows from a non-nested table item
ORA-06512: at line 10
ORA-06512: at line 19
The problem comes from the line 14 in that function
adm_usergroup.GET_GROUPIDS (userid_in)
If I replace the variable userid_in by its values then it perfectly works.
Can someone give me an explanation ?
The adm_usergroup.GET_GROUPIDS (userid_in) is a pipelined function that querry a group of tables and return IDs which are number.
A call to the function works fine as using it directly in a select statement.
Cheers,
Sebastien
1 DECLARE
2 l_groups AUTH_TYPE.GROUP_RT;
3 l_groups_rec authgroup%ROWTYPE;
4
5 FUNCTION GET_GROUPS (userid_in IN AUTHUSER.USERID%TYPE)
6 RETURN AUTH_TYPE.GROUP_RT
7 IS
8 l_groups_rt AUTH_TYPE.GROUP_RT;
9 BEGIN
10 OPEN l_groups_rt FOR
11 SELECT ag.*
12 FROM authgroup ag
13 WHERE AG.GROUPID IN
14 (SELECT * FROM table (adm_usergroup.GET_GROUPIDS (userid_in)));
15
16 RETURN l_groups_rt;
17 END GET_GROUPS;
18 BEGIN
19 l_groups := GET_GROUPS (1);
20
21 LOOP
22 FETCH l_groups INTO l_groups_rec;
23
24 EXIT WHEN l_groups%NOTFOUND;
25 DBMS_OUTPUT.put_line ('ID: ' || l_groups_rec.groupid);
26 END LOOP;
27
28 CLOSE l_groups;
29 END;by the way here is the full code
CREATE OR REPLACE PACKAGE AUTHDB.ADM_USERGROUP
IS
-- get the group and sub-group ids of a given user id
FUNCTION get_groupids (userid_in IN AUTHUSER.USERID%TYPE)
RETURN authgroup_set
PIPELINED;
END;
CREATE OR REPLACE PACKAGE BODY AUTHDB.ADM_USERGROUP
IS
FUNCTION get_groupids (userid_in IN AUTHUSER.USERID%TYPE)
RETURN authgroup_set
PIPELINED
IS
CURSOR group_cur
IS
SELECT mo.groupid
FROM memberof mo
WHERE MO.USERID = userid_in
UNION
SELECT gh.groupid
FROM GROUPHIERARCHY gh
CONNECT BY PRIOR GH.GROUPID = GH.PARENTGROUP_ID
START WITH GH.PARENTGROUP_ID IN (SELECT mo.groupid
FROM memberof mo
WHERE MO.USERID = userid_in);
BEGIN
FOR rec IN group_cur
LOOP
PIPE ROW (authgroup_type (REC.GROUPID));
END LOOP;
END;
END;
CREATE OR REPLACE
TYPE AUTHDB.AUTHGROUP_TYPE AS OBJECT (GROUPID NUMBER (10));
CREATE OR REPLACE
TYPE AUTHGROUP_SET AS TABLE OF authgroup_type;
DECLARE
l_groups AUTH_TYPE.GROUP_RT;
l_groups_rec authgroup%ROWTYPE;
FUNCTION GET_GROUPS (userid_in IN AUTHUSER.USERID%TYPE)
RETURN AUTH_TYPE.GROUP_RT
IS
l_groups_rt AUTH_TYPE.GROUP_RT;
BEGIN
OPEN l_groups_rt FOR
SELECT ag.*
FROM authgroup ag
WHERE AG.GROUPID IN
(SELECT * FROM table (cast(adm_usergroup.GET_GROUPIDS (userid_in) as authgroup_set)));
RETURN l_groups_rt;
END GET_GROUPS;
BEGIN
l_groups := GET_GROUPS (1);
LOOP
FETCH l_groups INTO l_groups_rec;
EXIT WHEN l_groups%NOTFOUND;
DBMS_OUTPUT.put_line ('ID: ' || l_groups_rec.groupid);
END LOOP;
CLOSE l_groups;
END; -
Hi ,
I test the routines found in http://sheikyerbouti.developpez.com/recordset/record_set.htm
I have a problem in the sample routine in Forms10g regarding pipelined function.
Whereas , the whole routine database part and client side in SQL*PLUS works fine.... the client side on Forms10g does not.......
I used two versions in when-button-pressed trigger:
1)Declare
cur SYS_REFCURSOR ;
begin
Open cur for SELECT * FROM TABLE(Pkg_Cur_.Get_Raws2(CURSOR(SELECT * FROM EMP WHERE DEPTNO = 10)));
end;
The error message in compilation time is..
Error 606: The subquery cursor is invalid in the client side
and the second version is:
2)Declare
tab Pkg_Cur_.REC_EMP_;
begin
tab:=Pkg_Cur_.GET_RAWS2('SELECT * FROM EMP WHERE DEPTNO = 10');
end;whereas the database package is defined as:
CREATE OR REPLACE PACKAGE Pkg_Cur_
IS
TYPE REC_EMP_ IS TABLE OF EMP%ROWTYPE INDEX BY BINARY_INTEGER ;
FUNCTION Get_Raws RETURN REC_EMP_ ;
FUNCTION Get_Raws2 ( cur_lig IN SYS_REFCURSOR )
RETURN TYPE_TAB_REC_EMP_ PIPELINED ;
END Pkg_Cur_ ;and the database package body is as follows:
CREATE OR REPLACE PACKAGE BODY Pkg_Cur_
IS
FUNCTION Get_Raws RETURN REC_EMP_
IS
TAB REC_EMP_;
BEGIN
SELECT * BULK COLLECT INTO TAB FROM EMP ;
RETURN TAB ;
END ;
FUNCTION Get_Raws2 ( cur_lig IN SYS_REFCURSOR )
RETURN TYPE_TAB_REC_EMP_ PIPELINED
IS
Trec TYPE_REC_EMP_ := TYPE_REC_EMP_(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL ) ;
Remp EMP%ROWTYPE ;
BEGIN
LOOP
FETCH cur_lig INTO Remp ;
EXIT WHEN cur_lig%NOTFOUND ;
-- Handling datas --
Trec.EMPNO := Remp.EMPNO ;
Trec.ENAME := Remp.ENAME ;
Trec.JOB := Remp.JOB ;
Trec.MGR := Remp.MGR ;
Trec.HIREDATE := Remp.HIREDATE ;
Trec.SAL := Remp.SAL * 1.1 ;
Trec.COMM := Remp.COMM ;
Trec.DEPTNO := Remp.DEPTNO ;
-- Return value --
PIPE ROW( Trec ) ;
END LOOP ;
RETURN ;
END ;
END Pkg_Cur_ ;
So , how the form trigger should be written...????
If somebody could help me i would be grateful...!!!!
Thanks a lot
SimonIn the second anonymous block you're trying to populate a record with a table. You would need to select from the function and either bulk collect into a table variable or fetch into a record variable in a loop. Bulk collect is also not supported on the client side.
I've been looking at pipelined function possibilities in another thread:
table functions
The problem you have is actually with the Cursor functions, not the Pipelined functions. -
PLS-00630: pipelined functions must have a supported collection return type
Hello, I created an TYPE of OBJECT and a PLSQL Function as shown below, but the function compilation errors with following. Not sure where is the issue?
PLS-00630: pipelined functions must have a supported collection return typeThis is on Oracle 10g r2
CREATE OR REPLACE TYPE cxs_plsql_profiler_object_type AS OBJECT (
cxs_object_name VARCHAR2 (128),
cxs_object_type VARCHAR2 (19),
cxs_object_status VARCHAR2 (7),
cxs_read_execution NUMBER,
cxs_buffer_gets NUMBER,
cxs_disk_reads NUMBER,
cxs_executions NUMBER,
cxs_sorts NUMBER,
cxs_sharable_mem NUMBER,
cxs_address NUMBER,
cxs_hashvalue NUMBER,
cxs_osuser VARCHAR2 (30),
cxs_username VARCHAR2 (30),
cxs_module VARCHAR2 (48),
cxs_machine VARCHAR2 (64),
cxs_status VARCHAR2 (8),
cxs_terminal VARCHAR2 (16),
cxs_percentconsume NUMBER,
cxs_percentrepeat NUMBER,
cxs_plan VARCHAR2 (120),
target_name VARCHAR2 (200),
referenced_name VARCHAR2 (200),
referenced_type VARCHAR2 (200),
targetowner VARCHAR2 (200),
refowner VARCHAR2 (200)
)and here is the API
FUNCTION CXS_GENERATE_PLSQL_PROFILER
RETURN cxs_plsql_profiler_object_type
PIPELINED IS
out_rec cxs_plsql_profiler_object_type ;
plsbatch plsql_batch;
skount integer;
dpendrec depend_tab;
dkount integer;
CURSOR objects
IS
SELECT object_name, object_type
FROM dba_objects
WHERE status = 'VALID'
AND owner NOT IN ('SYS', 'SYSTEM')
AND object_type IN ('PACKAGE', 'PROCEDURE', 'FUNCTION');
CURSOR apis (p_object dba_objects.object_name%TYPE)
IS
SELECT DISTINCT *
FROM (SELECT SUBSTR (a.sql_text, 1, 50) sql_text,
TRUNC
( a.disk_reads
/ DECODE (a.executions,
0, 1,
a.executions
) reads_per_execution,
a.buffer_gets, a.disk_reads, a.executions,
a.sorts, a.sharable_mem, a.address,
a.hash_value, b.osuser, b.username,
b.module, b.machine, b.status, b.terminal,
ROUND
(cxs_db_info.kompute_percentofsql
(a.sharable_mem),
5
) percentkonsume,
cxs_db_info.kount_repeat
(b.osuser,
b.terminal
) percentr,
c.operation explainplan
FROM v$sqlarea a, v$session b, v$sql_plan c
WHERE b.sql_hash_value = a.hash_value
AND b.sql_address = a.address
AND a.hash_value = c.hash_value
AND a.address = c.address
AND b.status = 'ACTIVE'
AND UPPER (a.sql_text) LIKE
'%' || p_object || '%'
AND c.ID = 0
ORDER BY 2 DESC)
WHERE ROWNUM <= 50; --profile option
BEGIN
skount := 0;
dkount := 0;
FOR i IN objects
LOOP
FOR j IN apis (i.object_name)
LOOP
skount := skount + 1;
plsbatch(skount).cxs_object_name := i.object_name;
plsbatch(skount).cxs_object_type := i.object_type;
plsbatch(skount).cxs_object_status := i.object_status;
plsbatch(skount).cxs_read_execution := j.reads_per_execution;
plsbatch(skount).cxs_buffer_gets := j.buffer_gets;
plsbatch(skount).cxs_disk_reads := j.disk_reads;
plsbatch(skount).cxs_executions := j.executions;
plsbatch(skount).cxs_sorts := j.sorts;
plsbatch(skount).cxs_sharable_mem := j.sharable_mem;
plsbatch(skount).cxs_address := j.address;
plsbatch(skount).cxs_hashvalue := j.hashvalue;
plsbatch(skount).cxs_osuser := j.osuser;
plsbatch(skount).cxs_username := j.username;
plsbatch(skount).cxs_module := j.module;
plsbatch(skount).cxs_machine := j.machine;
plsbatch(skount).cxs_status := j.status;
plsbatch(skount).cxs_terminal := j.terminal;
plsbatch(skount).cxs_percentconsume := j.percentconsume;
plsbatch(skount).cxs_percentrepeat := j.percentrepeat;
plsbatch(skount).cxs_plan := j.explainplan;
END LOOP;
FOR dd IN dpend (i.object_name)
LOOP
dkount := dkount + 1;
dependrec (dkount).target_name := dd.NAME;
dependrec (dkount).refname := dd.referenced_name;
dependrec (dkount).reftype := dd.referenced_type;
dependrec (dkount).target_owner := dd.owner;
dependrec (dkount).refowner := dd.referenced_owner;
END LOOP;
END LOOP;
for a in 1..skount loop
out_rec.cxs_object_type := plsbatch(a).object_type;
out_rec.cxs_object_status := plsbatch(a).object_status;
out_rec.cxs_read_execution := plsbatch(a).reads_per_execution;
out_rec.cxs_buffer_gets := plsbatch(a).buffer_gets;
out_rec.cxs_disk_reads := plsbatch(a).disk_reads;
out_rec.cxs_executions := plsbatch(a).executions;
out_rec.cxs_sorts := plsbatch(a).sorts;
out_rec.cxs_sharable_mem := plsbatch(a).sharable_mem;
out_rec.cxs_address := plsbatch(a).address;
out_rec.cxs_hashvalue := plsbatch(a).hashvalue;
out_rec.cxs_osuser := plsbatch(a).osuser;
out_rec.cxs_username := plsbatch(a).username;
out_rec.cxs_module := plsbatch(a).module;
out_rec.cxs_machine := plsbatch(a).machine;
out_rec.cxs_status := plsbatch(a).status;
out_rec.cxs_terminal := plsbatch(a).terminal;
out_rec.cxs_percentconsume := plsbatch(a).percentconsume;
out_rec.cxs_percentrepeat := plsbatch(a).percentrepeat;
out_rec.cxs_plan := plsbatch(a).explainplan;
PIPE ROW(out_rec);
end loop;
for b in 1..dkount loop
out_rec.target_name := dd.NAME;
out_rec.refname := dependrec (b).referenced_name;
out_rec.reftype := dependrec (b).referenced_type;
out_rec.target_owner := dependrec (b).owner;
out_rec.refowner := dependrec (b).referenced_owner;
PIPE ROW(out_rec);
end loop;
RETURN;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.format_error_backtrace);
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END; and below are tradtional table types that are used in code above.
TYPE type_plsql_rec IS RECORD (
cxs_object_name VARCHAR2 (128),
cxs_object_type VARCHAR2 (19),
cxs_object_status VARCHAR2 (7),
cxs_read_execution NUMBER,
cxs_buffer_gets NUMBER,
cxs_disk_reads NUMBER,
cxs_executions NUMBER,
cxs_sorts NUMBER,
cxs_sharable_mem NUMBER,
cxs_address NUMBER,
cxs_hashvalue NUMBER,
cxs_osuser VARCHAR2 (30),
cxs_username VARCHAR2 (30),
cxs_module VARCHAR2 (48),
cxs_machine VARCHAR2 (64),
cxs_status VARCHAR2 (8),
cxs_terminal VARCHAR2 (16),
cxs_percentconsume NUMBER,
cxs_percentrepeat NUMBER,
cxs_plan VARCHAR2 (120)
TYPE plsql_batch IS TABLE OF type_plsql_rec
INDEX BY BINARY_INTEGER;
TYPE type_depend_tab IS RECORD (
target_name dba_dependencies.NAME%TYPE,
refname dba_dependencies.referenced_name%TYPE,
reftype dba_dependencies.referenced_type%TYPE,
target_owner dba_dependencies.owner%TYPE,
refowner dba_dependencies.referenced_owner%TYPE
TYPE depend_tab IS TABLE OF type_depend_tab
INDEX BY BINARY_INTEGER;
Thank you for your time in reading this post
RThank you Billy and Saubhik,
I have followed your guidelines and was able to resolve this error. Now, after successfully compiling the code, I attempted to execute it in a following way.
SELECT * FROM TABLE (cxs_generate_plsql_profiler);It gives following error: ORA-00904: "CXS_GENERATE_PLSQL_PROFILER": invalid identifier
I also tried putting in quotes like below
SELECT * FROM TABLE ('cxs_generate_plsql_profiler');Then, it gives following error:
ORA-22905: cannot access rows from a non-nested table item
Any Idea where I am doing wrong?
Thanks,
R -
PL/SQL Pipelined Function to Compare *ANY* 2 tables
I am trying to create a pipelined function in 10g R1 that will take the name of two tables, compare the the tables using dynamic SQL and pipe out the resulting rows using the appropriate row type. The pipelined function will be used in a DML insert statement.
For example:
create table a (f1 number, f2, date, f3 varchar2);
create table b (f1 number, f2, date, f3 varchar2);
create table c (f1 number, f2, date, f3 varchar2);
create or replace TYPE AnyCollTyp IS TABLE OF ANYTYPE;
create or replace TYPE CRowType IS c%ROWTYPE;
create or replace TYPE CRowTabType IS table of CRowType;
CREATE OR REPLACE FUNCTION compareTables (p_source IN VARCHAR2, p_dest IN VARCHAR2)
RETURN AnyCollTyp PIPELINED
IS
CURSOR columnCur (p_tableName IN user_tab_columns.table_name%TYPE)
IS
SELECT column_name, column_id
FROM user_tab_columns
WHERE table_name = p_tableName
ORDER BY column_id;
l_cur sys_refcursor;
l_rec ANYTYPE;
l_stmt VARCHAR2 (32767);
BEGIN
l_stmt := 'select ';
FOR columnRec IN columnCur (p_dest)
LOOP
l_stmt := l_stmt || CASE
WHEN columnRec.column_id > 1
THEN ','
ELSE ''
END || columnRec.column_name;
END LOOP;
l_stmt := l_stmt || ' from ' || p_source;
l_stmt := l_stmt || ' minus ';
l_stmt := l_stmt || ' select ';
FOR columnRec IN columnCur (p_dest)
LOOP
l_stmt := l_stmt || CASE
WHEN columnRec.column_id > 1
THEN ','
ELSE ''
END || columnRec.column_name;
END LOOP;
l_stmt := l_stmt || ' from ' || p_dest;
OPEN l_cur FOR l_stmt;
LOOP
FETCH l_cur
INTO l_rec;
PIPE ROW (l_rec);
EXIT WHEN l_cur%NOTFOUND;
END LOOP;
CLOSE l_cur;
RETURN;
END compareTables;
The pipelined function gets created without error. However, the testCompare procedure gets an error:
SQL> create or replace procedure testCompare is
begin
insert into c
select *
from (TABLE(CAST(compareTables('a','b') as cRowTabType)));
dbms_output.put_line(SQL%ROWCOUNT || ' rows inserted into c.');
end;
Warning: Procedure created with compilation errors.
SQL> show errors
Errors for PROCEDURE TESTCOMPARE:
LINE/COL ERROR
3/4 PL/SQL: SQL Statement ignored
5/47 PL/SQL: ORA-22800: invalid user-defined type
Does anyone know what I am doing wrong? Is there a better way to compare any two tables and get the resulting rows?904640 wrote:
Hi All,
Is it possible to post messages to weblogic JMS queue from pl/sql procedure/function?
From this Queue, message will be read by OSB interface.
Any help will be highly appreciated.
http://www.lmgtfy.com/?q=oracle+pl/sql+weblogic+jms+queue -
How to convert this package from 11g to 10g (still using dbms_sql) ?
create or replace package pkg_test is
type tab_t is table of ra_analista%rowtype;
function pipeValues return tab_t pipelined;
function selValues return sys_refcursor;
end;
create or replace package body pkg_test is
function pipeValues
return tab_t pipelined is
cr sys_refcursor;
tab tab_t;
cnt int;
cmd pls_integer := dbms_sql.open_cursor;
begin
dbms_sql.parse(cmd, 'select * from RA_Analista', dbms_sql.native);
cnt := dbms_sql.execute(cmd);
cr := dbms_sql.to_refcursor(cmd);
fetch cr bulk collect into tab;
if tab.count > 0 then
for i in tab.first .. tab.last loop
pipe row(tab(i));
end loop;
end if;
return;
end;
function selValues return sys_refcursor is
c1 sys_refcursor;
begin
open c1 for select * from table(pipeValues);
return c1;
end;
end;Create Or Replace Package Body Pkg_Test Is
Function Pipevalues Return Tab_t Pipelined Is
Cr Sys_Refcursor; Tab Tab_t; Cnt Int; Cmd Pls_Integer := Dbms_Sql.Open_Cursor;
Begin
Dbms_Sql.Parse(Cmd, 'select * from RA_Analista', Dbms_Sql.Native); --**there in 10g**
Cnt := Dbms_Sql.Execute(Cmd); --**there 10g**
Cr := Dbms_Sql.To_Refcursor(Cmd); --**no need to use ref cursor here....if you want to use it go for open for instead of dbms_sql**
Fetch Cr Bulk Collect Into Tab;
If Tab.Count > 0 Then For i In Tab.First .. Tab.Last Loop Pipe Row(Tab(i));
End Loop;
End If; Return;
End;Edited by: Nicloei W on Sep 16, 2008 6:26 PM
Edited by: Nicloei W on Sep 16, 2008 6:26 PM
Edited by: Nicloei W on Sep 16, 2008 6:27 PM -
Pipelined function ignores DML changes on subqueries
Hello all,
I have a really specific issue when using a pipelined function used in a complex subquery where the function ignores the changes made on the current transaction. The problem is the hidden hint materialize sometimes used by the Oracle optimizer. I say sometimes because it depends mostly on the execution plan and the complexity of the query.
I can repeat the problem with a dummy scenario.
Let's say we have a dummy table with a simple record :
CREATE TABLE DUMMY ("NAME" VARCHAR2(50 BYTE));
INSERT INTO DUMMY VALUES('Original name');
We then create a package which will contain our pipelined function and its record object and collection:
CREATE OR REPLACE PACKAGE PKG_DUMMY AS
TYPE DUMMY_RECORD IS RECORD (NAME VARCHAR2(50 BYTE));
TYPE DUMMY_RECORDS IS TABLE OF DUMMY_RECORD;
FUNCTION FUNC_GET_DUMMY_NAME RETURN DUMMY_RECORDS PIPELINED;
END PKG_DUMMY;
CREATE OR REPLACE
PACKAGE BODY PKG_DUMMY AS
FUNCTION FUNC_GET_DUMMY_NAME RETURN DUMMY_RECORDS PIPELINED AS
BEGIN
FOR CUR IN ( SELECT * FROM DUMMY )
LOOP
PIPE ROW (CUR);
END LOOP;
END FUNC_GET_DUMMY_NAME;
END PKG_DUMMY;
With this SQL query, we can return the value of the table by the pipelined function :
WITH DUMMY_NAME AS
SELECT "NAME"
FROM TABLE(PKG_DUMMY.FUNC_GET_DUMMY_NAME())
SELECT "NAME"
FROM DUMMY_NAME
Result
Original name
If we modify the DUMMY table with a new name without a commit, and re-execute the query, we got the same result :
UPDATE DUMMY SET "NAME" = 'New name';
Result
New name
But if we add the materialize hint in the subquery (without doing a commit or rollback), we have the original value hence my issue :
WITH DUMMY_NAME AS
SELECT /*+ materialize */ "NAME"
FROM TABLE(PKG_DUMMY.FUNC_GET_DUMMY_NAME())
SELECT "NAME"
FROM DUMMY_NAME
Result
Original name
I know I can force my subquery to use an inline hint instead of the "materialize" hint chose by the optimizer but then the query lose a lot of performance. Is there a way to force Oracle to use current DML changes with the materialize hint on a pipelined funtion in a subquery?
This thread is also for this issue : http://stackoverflow.com/questions/1597467/is-using-a-select-inside-a-pipelined-pl-sql-table-function-allowedHi Eliante, Hi Dominic,
Very Interesting. Here what I can reproduce in Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
sql > truncate table dummy;
Table truncated.
sql >INSERT INTO DUMMY VALUES('Original name');
1 row created.Please pay attention that I didn't commit
sql > with dummy_name as
2 (
3 select "NAME"
4 from table(pkg_dummy.func_get_dummy_name())
5 )
6 select "NAME"
7 from dummy_name;
NAME
Original name
sql> start c:\dispcursor
PLAN_TABLE_OUTPUT
SQL_ID 838mtur4m74j2, child number 0
with dummy_name as ( select "NAME" from table(pkg_dummy.func_get_dummy_name()) ) select "NAME"
from dummy_name
Plan hash value: 117055
| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers |
| 1 | COLLECTION ITERATOR PICKLER FETCH| FUNC_GET_DUMMY_NAME | 1 | 1 |00:00:00.01 | 15 |
Note
- rule based optimizer used (consider using cbo)
17 rows selected.
sql > with dummy_name as
2 (
3 select /*+ materialize */ "NAME"
4 from table(pkg_dummy.func_get_dummy_name())
5 )
6 select "NAME"
7 from dummy_name;
no rows selected
sql >start c:\dispcursor
PLAN_TABLE_OUTPUT
SQL_ID 9frx3wjk992rd, child number 0
with dummy_name as ( select /*+ materialize */ "NAME" from table(pkg_dummy.func_get_dummy_name()) ) select "NAME" from dummy_name
Plan hash value: 1359790764
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
| 1 | TEMP TABLE TRANSFORMATION | | 1 | | 0 |00:00:00.01 | 20 | | | |
| 2 | LOAD AS SELECT | | 1 | | 0 |00:00:00.01 | 19 | 1024 | 1024 | |
| 3 | COLLECTION ITERATOR PICKLER FETCH| FUNC_GET_DUMMY_NAME | 1 | | 0 |00:00:00.01 | 17 | | | |
| 4 | VIEW | | 1 | 8168 | 0 |00:00:00.01 | 0 | | | |
| 5 | TABLE ACCESS FULL | SYS_TEMP_0FD9D780C_BD7649E3 | 1 | 8168 | 0 |00:00:00.01 | 0 | | | |
16 rows selected.I can point out that the TABLE ACCESS FULL of the global temporary SYS_TEMP_0FD9D780C_BD7649E3 table created by Oracle in response to the -materialize hint is returning *0 rows* in operation 5.
Why?
It seems for me that the reason for that comes from the fact that the creation of this SYS_TEMP_0FD9D780C_BD7649E3 table is done via direct path read/direct path write and as far as
the insert of *'Original name'* has not been pushed yet into the disc then materializing the query will generate an empty temporary table (empty in this case).
This is why if I had committed I will not have seen such a kind of discrepancy between those two queries
What do you think?
Mohamed Houri
www.hourim.wordpress.com
Maybe you are looking for
-
Problem with sound in p55 gd65
hello i have a problem in my system and i dont know its from mainbord or other devices when i playing game or watching movie,suddenly the sound is cutting down(stoping) and cpu usage going up(25 or 30 %) in game i had no sound and game play was with
-
Delaying folder action until file creation is complete
I'm trying to create a folder action that takes the output of a bounce from ProTools and then imports it into iTunes. The problem I'm having is that it takes real time (about 20 min) to create the complete ProTools file in the folder, however the scr
-
Getting error IMPORT_WRONG_END_POS while changing the order
Hi All, in Capital investment order, i am trying to change the operation data for service (PM03) for which PR has been created already, i am getting abap runtime error. FM is active for order type and PO has not been created yet. Runtime Errors
-
PE9 trial on Mac Pro - .mp4 is almost unworkable
I've installed the trial version of PE9 on my Mac Pro (2x2.8GHz quad-core with 10 GB RAM). It works well with MPEG-2 files from my DVD recorder (recorded TV broadcasts), but it bogs down seriously on .mp4 files exported from Elgato's EyeTV. Even wi
-
how can I access to my time capule remotely with icloud?