Pipeline function problem
oracle db version 9.2.0.7
create or replace TYPE ENAME_T AS OBJECT (name varchar2(10));
create or replace TYPE ENAME_NT AS TABLE OF ename_t;
CREATE OR REPLACE FUNCTION GET_ENAME (comm IN number)
RETURN ename_nt PIPELINED
IS
v_comm number := comm;
v_ename_t ename_t;
BEGIN
for v_ename in (select ename from emp where comm > v_comm) loop
v_ename_t := ename_t(v_ename);
pipe row (v_ename_t);
end loop;
return;
END;
Error(10,18): PLS-00306: wrong number or types of arguments in call to 'ENAME_T'
I do not see why I am getting this message. What can I do to can the results of the sql "select ename from emp where comm > v_comm" in a pipeline function
thanks
try
v_ename_t := ename_t(v_ename.ename);
should work
Similar Messages
-
Interactive Report using a View with a Pipelined Function
Hello fellow Apex people,
I'm Using Application Express 4.1.0.00.32
I've got an interactive report that references a view (STOCK) and a pipelined function
The basic query is listed below.
SELECT S.CHANGED_TIME "Changed Time"
, S.CHANGED_BY "Changed By"
, S.ID "Id"
, STKST_DESCRS.STOCK_STATUS_CODES "Stock Status Codes"
, STKST_DESCRS.STOCK_STATUS_DESCRS "Stock Status"
, S.ORIGINAL_CONTAINER "Original Container"
FROM STOCK S
, table(LWS_StkstStatus (S.ID)) STKST_DESCRS
ORDER BY S.CO_ID,
S.SEQUENCE_NUM;
When the page is first run all the data is displayed correctly,
If I define a filter, sort or a blank search the data from the pipelined function (STKST_DESCRS.) becomes null and isn't displayed.
Does anyone know what is happening?
Many ThanksI'm curious why you find this dangerous. I want a report that looks like this:
Opportunity X:
4 - 2-apr-2008 - Closed deal
3 - 1-mar-2008 - Called Joe again
2 - 12-feb-2008 - Called Joe
1 - 14-jan-2008 - Initial call with customer.
When you enter a new note, I want it to be numbered 5. The only problem I can imagine is someone deleting a note, which will almost never happen, and if it does, it just leaves a numbering gap. I don't see how using the function in a SELECT will accomplish this. -
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 -
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. -
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 -
Pipelined function with huge volume
Hi all,
I have a table of 5 million rows with an average length of 1K for each row (dss system).
My SGA is 2G and PGA 1G.
I wonder if a pipelined function could support a such volume ?
Does anyone have already experienced a pipelined function with a huge volume ?
TIA
YangHello
Well, just over a month later and we're pretty much sorted. Our pipelined functions were not the cause of the excessive memory consumption and the processes are are now no longer consuming as much PGA as they were previously. Here's what I've learnt.
1. Direct write operations on partitioned tables require two direct write buffers to be allocated per partition. By default, these buffers are 256K each so it's 512K per partition. We had a table with 241 partitions which meant we inadvertently allocating 120MB of PGA without even trying. This is not a problem with pipelined functions.
2. In 10.2 the total size of the buffers will be kept below the pga_aggregate_target, or 64k per buffer, whichever is higher. This is next to useless though as to really constrain the size of the buffers at all, you need a ridiculously small pga_aggregate_target.
3. The size of the buffers can be as low as 32k and can be set using an undocumented parameter "_ldr_io_size". In our environment (10.2.0.2 Win2003 using AWE) I've set it to 32k meaning there will be 64k worth of buffers allocated to each partition significantly reducing the amount of PGA required.
4. I never want to speak to Oracle support again. We had a severity 1 SR open for over a month and it took the development team 18 days to get round to looking at the test case I supplied. Once they'd looked at it, they came back with the undocumented parameter which worked, and the ridiculous suggestion that I set the PGA aggregate target to 50MB on a production box with 4GB and 300+ dedicated connections. No only that, they told me that a pga_aggregate_target of 50MB was sensible and did so in the most patronising way. Muppets.
So in sum, our pipelined functions are working exceptionally well. We had some scary moments as we saw huge amounts of PGA being allocated and then 4030 memory errors but now it's sorted and chugging along nicely. The throughput is blistering especially when running in parallel - 200m rows generated and inserted in around 1 hour.
To give some background on what we're using pipelined functions for....
We have a list of master records that have schedules associated with them. Those schedules need to be exploded out to an hourly level and customised calendars need to be applied to them along with custom time-zone-style calculations. There are various lookups that need to be applied to the exploded schedules and a number of value calculations based on various rules. I did originally implement this in straight SQL but it was monsterous and ran like a dog. The SQL was highly complex and quite quickly became unmanageable. I decided to use pipelined functions because
a) It immensely simplified the logic
b) It gave us a very neat way to centralise the logic so it can be easily used by other systems - PL/SQL and SQL
c) We can easily see what it is doing and make changes to the logic without affecting execution plans etc
d) Its been exceptionally easy to tune using DBMS_PROFILER
So that's that. I hope it's of use to anyone who's interested.
I'm off to get a "pipelined fuinctions rule" tattoo on my face.
David -
Good Morning
Can anyone help me to get started writting a pipelined function to convert a table like this
Name Period start Period End
Smith 3 5
Smith 7 10
Smith 12 16
into a table tike this
Name Periods
Smith ooXXXoXXXXoXXXXXooooo
or may be there is a simpler way of doing this?
Thanks
David HillsThere's more to this problem than simple column concatenation. There is some processing reuired to fill the gaps between the start and end points of the periods.
The following code takes a blunt instrument approach: pipelined function and bit masks. Perhaps some of the brains on this forum can come up with a more elegant approach. The function does, at least, have the virtue of working:
SQL> select * from table( timelines)
2 /
NAME TIMELINE
Jones oooXXXXXooXXoooooooXXXXX
Smith ooXXXoXXXXoXXXXXoooooooo
SQL>Note that this code is very much a "coffee time" proof of concept, and contains a number of infelicitous repetitions. Improving this code is left as an exercise for the reader.
Cheers, APC
CREATE TABLE periods (Name varchar2 (10), Pstart number, Pend number)
INSERT INTO periods VALUES ('Smith', 3, 5)
INSERT INTO periods VALUES ('Smith', 7 ,10)
INSERT INTO periods VALUES ('Smith', 12, 16)
INSERT INTO periods VALUES ('Jones', 4, 8)
INSERT INTO periods VALUES ('Jones', 11 ,12)
INSERT INTO periods VALUES ('Jones', 20, 24)
CREATE OR REPLACE TYPE tl_t AS OBJECT (name varchar2(10), timeline varchar2(24));
CREATE OR REPLACE TYPE tl_nt AS TABLE OF tl_t
CREATE OR REPLACE FUNCTION timelines
RETURN tl_nt
PIPELINED
IS
TYPE masks IS TABLE OF RAW(24) INDEX BY PLS_INTEGER;
timeslot masks;
return_value tl_t := tl_t(null, null);
slots RAW(24);
PROCEDURE pop_timeslot IS
BEGIN
timeslot(1) := utl_raw.cast_to_raw('100000000000000000000000');
timeslot(2) := utl_raw.cast_to_raw('010000000000000000000000');
timeslot(3) := utl_raw.cast_to_raw('001000000000000000000000');
timeslot(4) := utl_raw.cast_to_raw('000100000000000000000000');
timeslot(5) := utl_raw.cast_to_raw('000010000000000000000000');
timeslot(6) := utl_raw.cast_to_raw('000001000000000000000000');
timeslot(7) := utl_raw.cast_to_raw('000000100000000000000000');
timeslot(8) := utl_raw.cast_to_raw('000000010000000000000000');
timeslot(9) := utl_raw.cast_to_raw('000000001000000000000000');
timeslot(10) := utl_raw.cast_to_raw('000000000100000000000000');
timeslot(11) := utl_raw.cast_to_raw('000000000010000000000000');
timeslot(12) := utl_raw.cast_to_raw('000000000001000000000000');
timeslot(13) := utl_raw.cast_to_raw('000000000000100000000000');
timeslot(14) := utl_raw.cast_to_raw('000000000000010000000000');
timeslot(15) := utl_raw.cast_to_raw('000000000000001000000000');
timeslot(16) := utl_raw.cast_to_raw('000000000000000100000000');
timeslot(17) := utl_raw.cast_to_raw('000000000000000010000000');
timeslot(18) := utl_raw.cast_to_raw('000000000000000001000000');
timeslot(19) := utl_raw.cast_to_raw('000000000000000000100000');
timeslot(20) := utl_raw.cast_to_raw('000000000000000000010000');
timeslot(21) := utl_raw.cast_to_raw('000000000000000000001000');
timeslot(22) := utl_raw.cast_to_raw('000000000000000000000100');
timeslot(23) := utl_raw.cast_to_raw('000000000000000000000010');
timeslot(24) := utl_raw.cast_to_raw('000000000000000000000001');
END pop_timeslot;
BEGIN
pop_timeslot;
FOR rec IN (SELECT * FROM periods ORDER BY name, pstart) LOOP
IF return_value.name IS NULL
THEN
return_value.name := rec.name;
slots := utl_raw.cast_to_raw('000000000000000000000000');
ELSIF rec.name != return_value.name
THEN
return_value.timeline := translate(utl_raw.cast_to_varchar2(slots), '01', 'oX');
pipe row( return_value );
return_value.name := rec.name;
slots := utl_raw.cast_to_raw('000000000000000000000000');
END IF;
FOR i IN rec.pstart..rec.pend LOOP
slots := utl_raw.bit_or(slots, timeslot(i));
END LOOP;
END LOOP;
return_value.timeline := translate(utl_raw.cast_to_varchar2(slots), '01', 'oX');
pipe row( return_value );
RETURN;
END timelines;
/ -
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> -
Apex3.2.1 pipelined functions with parameters send cpu to 100 percent
I have just installed 11g and exported a schema from 10g into it.
When I run Apex3.2.1 and open a page with a flash chart that running off a table object populated by a pipelined function the CPU goes in overload 100%.
I have tracked the problem to parameters on the pipelined function if I use bind parameters( :P640_YEARS, :P640_EMPLOYER_ID) then the problem happens but if I hard code values all is fine (2010,99).
This happens with every flash chart we have, which makes our application and database unusable.
Any ideas.
DerekThanks very much for the posts, I took the opportunity to upgrade to Apex 4.0.2 as suggested by Patrick and the application works fine again now.
Interestingly I did re-analyse the statistics but only as a reaction to the problem, should have been done regardless.
I did consider re-writing the pipelined functions but to be honest it would have been difficult as they are extremely complex, I wasn't looking forward to the task. I have become quite a fan of pipelined functions for building flash charts, dash boards extra, its as always about tuning the sql.
Thanks very to all
Derek
Edited by: 835735 on Feb 10, 2011 1:50 PM -
Pipeline function raised ORA-06519: active autonomous transaction detected
Hi All,
My name is John and I've got a problem which I need to share with all of you guru and experts. I've created the following pipeline function under the Oracle user ABC:
CREATE OR replace FUNCTION SomeFunction(p_from_date DATE, p_to_date DATE) RETURN T_TAB_A pipelined
IS
PRAGMA autonomous_transaction;
BEGIN
DELETE FROM temp_rcm;
INSERT INTO temp_rcm
SELECT * FROM int.facility fd,
int.capacity co
WHERE co.resource_name = fd.resource_name
AND co.trade_date = fd.trade_date
AND co.trade_date BETWEEN p_from_date AND p_to_date;
COMMIT;
FOR rec IN (SELECT co.*
FROM temp_rcm co
left join int.outage o
ON ( o.flag = 'Y'
AND o.reason_flag = 'F'
AND o.INTERVAL = co.INTERVAL
AND co.resource_name = o.resource_name )
ORDER BY co.INTERVAL,
co.name) LOOP
pipe ROW (T_A( rec.INTERVAL, rec.trade_date,
rec.resource_name,rec.day_of_week_long, rec.working_day, rec.peak));
END LOOP;
RETURN;
END SomeFunction;
I was able to compile and create the SomeFunction function successfully but when I executed it using the following command:
select * from table(SomeFunction(to_date('01/01/2010',to_date('01/01/2010')));
I was returned with the Oracle error - ORA-06519: active autonomous transaction detected and rolled back
I have searched through the web, such Oracle error occurs whenever the function has a missing 'COMMIT' or 'ROLLBACK' command inside an autonomous_transaction. But the fact is I have already included the 'COMMIT;' in the function. I suspected that the error was caused by the tables which I queried against (like int.facility and int.capacity) were all views that belonged to another schema called int. Or is that something that I miss in the function? Thank you for your time and assistance.
Regards,
Johnjohnwanng wrote:
Hi Guys,
Thank you for all your feedback. In addition to your reply, Bill, can you spare some time and provide us a simple example of the steps involved to implement the 'correct' implementation based on the queries that I've used. As I do not understand your vanilla approach. Much appreciated and thank you for the time again.
Regards,
JohnIf I had to guess, Billy may have meant something like this (untested):
CREATE OR REPLACE FUNCTION SomeFunction
( p_from_date IN int.facility.trade_date%TYPE
, p_to_date IN int.facility.trade_date%TYPE
RETURN SYS_REFCURSOR
AS
rcur SYS_REFCURSOR;
BEGIN
OPEN rcur FOR
SELECT co.interval
, co.trade_date
, co.resource_name
, co.day_of_week_long
, co.working_day
, co.peak
FROM int.capacity co
JOIN int.facility fd ON fd.resource_name = co.resource_name
AND fd.trade_date = co.trade_date
LEFT OUTER JOIN int.outage o ON o.interval = co.interval
AND o.resource_name = co.resource_name
WHERE co.trade_date BETWEEN p_from_date AND p_to_date
AND o.reason_flag = 'F'
AND o.flag = 'Y'
ORDER BY co.interval
, co.name
RETURN rcur;
END;
/I made the following modifications:
1. I set the input parameter data types to match that of the table column you are checking against. A good practice to get into.
2. Removed the autonomous transaction and inserting into a temp table. In Oracle it's a good practice to perform everything in a single SQL statement if possible.
3. Changed the return data type to a SYS_REFCURSOR
Hope this helps and provides a good example. -
PipeLine Function Taking time to return Table record
Hi,
I want to use a function in join clause. so i go for pipelined function(using for loop to get record & 1 more loop to fetch in table type variable). i achieved what i required. but problem is it takes much time to fetch data. is there any other approach which returns table records without pipelined function.
please suggest me a better approach as soon as possible.Hi,
Thanks all for the quick response.
I am using oracle 10g
this is the table details & the entire function.
Create object & table type to use in the function
CREATE OR REPLACE TYPE SYSADM.STR_TYPE AS OBJECT(COLUMNVALUE VARCHAR2(8),FromNo Int,ToNo Int)
CREATE OR REPLACE TYPE SYSADM.STR_ARRAY AS TABLE OF STR_TYPE
table involved
View : VesselType
column : Code varchar2(5)
Table : T065_SHIP
column : SKIPS_KODE varchar2(4)
CODE_SHIPTYPE varchar2(5)
Table : SelsKap
column : SELSKAPSKODE varchar2(4)
Table : t041_shiptypeusers
column : Code_ShipType varchar2(5)
USERID varchar2(8)
View : PositionBook
column : VesselCode varchar2(8)
VoyageNo integer
Company varchar2(4)
Table : T62_BRUKER_SELSKAP
column : SELSKAPSKODE varchar2(4)
BRUKER varchar2(8)
Pipelined function
CREATE OR REPLACE FUNCTION SYSADM.TF_ShiporShipTypeByUser
In_UserName IN VARCHAR2,
In_Type IN VARCHAR2,
In_VesselCode IN VARCHAR2,
In_CompanyHistory IN NUMBER DEFAULT 0
RETURN str_array PIPELINED AS
l_ShipTypeUser NUMBER(10,0);
l_CompanyUser NUMBER(10,0);
l_UseCompanyHistory NUMBER(1,0);
l_Snicsacct NUMBER(1,0);
BEGIN
BEGIN
SELECT shiptype_user,
company_user
INTO l_ShipTypeUser,
l_CompanyUser
FROM User_Segregation;
EXCEPTION
WHEN OTHERS THEN
l_ShipTypeUser := NULL;
l_CompanyUser := NULL;
END;
BEGIN
SELECT 1 INTO l_Snicsacct
FROM DUAL
WHERE NOT EXISTS ( SELECT 1 FROM sn_user_cfg WHERE UserID='SNICS' and CfgID='ACCTSYS');
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
IF In_CompanyHistory = 1
THEN
BEGIN
SELECT CfgData
INTO l_UseCompanyHistory
FROM SN_User_Cfg
WHERE CfgID = 'USE COMPANY HISTORY'
AND UserID = 'SNICS';
EXCEPTION
WHEN OTHERS THEN
l_UseCompanyHistory := 0;
END;
END IF;
IF In_UserName = 'SYSADM' OR (l_CompanyUser = 0 AND l_ShipTypeUser = 0)
OR (l_CompanyUser = 1 and l_Snicsacct =1 ) or (In_CompanyHistory = 0 and l_CompanyUser = 1 and In_Type ='ShipType')
OR (l_ShipTypeUser = 1 and In_Type = 'Company')
THEN
BEGIN
IF In_Type = 'ShipType'
THEN
BEGIN
FOR cur IN (SELECT Code ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM VesselType )
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
ELSIF In_Type = 'Ship'
THEN
BEGIN
FOR cur IN (SELECT SKIPS_KODE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP
WHERE SKIPS_KODE = NVL(In_VesselCode,SKIPS_KODE ))
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
ELSIF In_Type = 'Company'
THEN
BEGIN
FOR cur IN (SELECT SELSKAPSKODE ShipCode
, NULL VoyageFrom
, NULL VoyageTo
FROM SelsKap)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
END IF;
END;
ELSE
IF In_Type = 'Ship'
THEN
BEGIN
IF l_ShipTypeUser =1
THEN
BEGIN
FOR cur IN (SELECT S.SKIPS_KODE ShipCode
, 1 FromVoyage
, 999999999 ToVoyage
FROM T065_SHIP S
JOIN t041_shiptypeusers U
ON S.CODE_SHIPTYPE = U.Code_ShipType
AND USERID = In_UserName
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
GROUP BY S.SKIPS_KODE)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.FromVoyage,cur.ToVoyage));
END LOOP;
RETURN;
END;
ELSIF l_CompanyUser = 1
THEN
BEGIN
IF l_UseCompanyHistory = 1 AND In_CompanyHistory = 1
THEN
FOR cur IN (SELECT a.VesselCode ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
JOIN T62_BRUKER_SELSKAP b
ON a.Company = b.SELSKAPSKODE
AND b.BRUKER = In_UserName
WHERE a.VesselCode = NVL(In_VesselCode, a.VesselCode)
UNION
SELECT a.VesselCode ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.company = b.SELSKAPSKODE
WHERE a.VesselCode = NVL(In_VesselCode, a.VesselCode)
AND b.SELSKAPSKODE IS NULL
GROUP BY a.VesselCode,
a.VoyageNo,
a.VoyageNo)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
ELSE
FOR cur IN (SELECT a.SKIPS_KODE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP a
JOIN T62_BRUKER_SELSKAP b
ON a.Company = b.SELSKAPSKODE
AND b.BRUKER = In_UserName
WHERE a.SKIPS_KODE = NVL(In_VesselCode, a.SKIPS_KODE)
AND NVL(l_UseCompanyHistory,0) = 0
UNION
SELECT a.SKIPS_KODE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.company = b.SELSKAPSKODE
WHERE a.SKIPS_KODE = NVL(In_VesselCode, a.SKIPS_KODE)
AND b.SELSKAPSKODE IS NULL
GROUP BY a.SKIPS_KODE)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END IF;
END;
END IF;
END;
ELSIF In_Type = 'ShipType'
THEN
IF l_ShipTypeUser = 1
THEN
BEGIN
FOR cur IN (SELECT S.CODE_SHIPTYPE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP S
JOIN t041_shiptypeusers U
ON S.CODE_SHIPTYPE = U.Code_ShipType
AND USERID = In_UserName
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
GROUP BY S.CODE_SHIPTYPE)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
ELSIF l_CompanyUser = 1
THEN
IF l_UseCompanyHistory = 1 AND In_CompanyHistory = 1
THEN
BEGIN
FOR cur IN (SELECT a.VesselType ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
JOIN T62_BRUKER_SELSKAP b
ON a.COMPANY = b.SELSKAPSKODE
AND b.BRUKER = In_UserName
WHERE a.VesselCode = NVL(In_VesselCode,a.VesselCode)
UNION
SELECT a.VesselType ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.company = b.SELSKAPSKODE
WHERE a.VesselCode = NVL(In_VesselCode, a.VesselCode)
AND b.SELSKAPSKODE IS NULL
GROUP BY a.VesselType,
a.VoyageNo,
a.VoyageNo)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
ELSE
BEGIN
FOR cur IN (SELECT S.CODE_SHIPTYPE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP S
JOIN T62_BRUKER_SELSKAP b
ON S.company = b.SELSKAPSKODE
AND B.BRUKER = In_UserName
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
AND NVL(l_UseCompanyHistory,0) = 0
UNION
SELECT S.CODE_SHIPTYPE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP S
LEFT JOIN T62_BRUKER_SELSKAP b
ON S.company = b.SELSKAPSKODE
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
AND b.SELSKAPSKODE IS NULL)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
END IF;
END IF;
ELSIF In_Type = 'Company'
THEN
BEGIN
FOR cur IN (SELECT a.SELSKAPSKODE ShipCode
, NULL VoyageFrom
, NULL VoyageTo
FROM Selskap a
JOIN T62_BRUKER_SELSKAP b
ON a.SELSKAPSKODE = b.SELSKAPSKODE
WHERE b.BRUKER = In_UserName
Union All
Select a.SELSKAPSKODE ShipCode
, NULL VoyageFrom
, NULL VoyageTo
From Selskap a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.SELSKAPSKODE = b.SELSKAPSKODE
Where b.SELSKAPSKODE IS NULL
GROUP BY a.SELSKAPSKODE)
LOOP
PIPE ROW(str_type(cur.ShipCode,cur.VoyageFrom,cur.VoyageTo));
END LOOP;
RETURN;
END;
END IF;
END IF;
END;
select statement which i call the function it takes minimum 6 seconds to execute. It gives 8339 records
WITH deftbl AS ( SELECT /*+ CACHE(deftbl) */
/*+ result_cache */
a.VesselCode,
a.VoyageNo,
CASE a.BallastLeg When 0
THEN MIN(a.ArrivalDate)
ELSE NVL(( SELECT MAX(DepartureDate)
FROM PositionBook b
WHERE b.VesselCode = a.VesselCode
AND b.VoyageNo = (Select MAX(VoyageNo) From PositionBook c Where c.VesselCode = a.VesselCode and c.VoyageNo<a.VoyageNo)
),MIN(a.ArrivalDate))
END AS StartOfVoyage,
MAX(DepartureDate) EndOfVoyage
FROM PositionBook a
JOIN TABLE(*TF_ShiporShipTypeByUser*('BKA', 'Ship', NULL, 1)) D /*Calling the function*/
ON D.ColumnValue = a.VesselCode
AND a.VoyageNo BETWEEN D.FromVoyageNo AND D.ToVoyageNo
GROUP BY VesselCode,VoyageNo,a.BallastLeg )
SELECT /*+ result_cache */
ROW_NUMBER() OVER(PARTITION BY a.VesselCode ORDER BY a.VoyageNo DESC) as "Row"
,a.VesselCode
,v.Name AS VesselName
,a.VoyageNo
,c.StartOfVoyage AS FromPort
,c.EndOfVoyage AS ToPort
/*,a.FROMPORT
,a.TOPORT*/
, CASE
WHEN ( SELECT PortName
FROM PositionBook b
WHERE b.VesselCode = a.VesselCode
AND b.VoyageNo = a.VoyageNo
AND SYSDATE BETWEEN ArrivalDate AND DepartureDate ) IS NOT NULL
THEN ( SELECT FIRST_VALUE(PortName) OVER(PARTITION BY b.vesselcode,b.VoyageNo ORDER BY b.vesselcode,b.VoyageNo,b.ArrivalDate,b.secondarytime)
FROM PositionBook b
WHERE b.VesselCode = a.VesselCode
AND b.VoyageNo = a.VoyageNo
AND SYSDATE BETWEEN ArrivalDate AND DepartureDate
AND ROWNUM=1
WHEN SYSDATE BETWEEN c.StartOfVoyage AND c.EndOfVoyage
THEN ( SELECT 'Steam From '||FIRST_VALUE(UPPER(PortName)) OVER(PARTITION BY b.vesselcode,b.VoyageNo ORDER BY b.vesselcode,b.VoyageNo,b.ArrivalDate desc,b.secondarytime desc)
FROM POSITIONBOOK b
WHERE b.VesselCode = a.VesselCode AND b.VoyageNo = a.VoyageNo
AND b.ArrivalDate<SYSDATE
AND ROWNUM=1
WHEN (c.StartOfVoyage-SYSDATE)>0
THEN 'Voyage Not Started'
WHEN (c.EndOfVoyage-SYSDATE)<0
THEN 'Voyage Completed'
ELSE Null
END "Location"
,( SELECT MIN(b.PortName) KEEP(DENSE_RANK FIRST ORDER BY b.ArrivalDate,b.secondarytime) OVER(PARTITION BY b.VesselCode,b.VoyageNo)
FROM POSITIONBOOK b
WHERE b.VesselCode = a.VesselCode AND b.VoyageNo = a.VoyageNo
AND b.ArrivalDate>SYSDATE
AND ROWNUM=1
) AS NextPort
, ( SELECT MIN(b.ArrivalDate) KEEP(DENSE_RANK FIRST ORDER BY b.ArrivalDate,b.secondarytime) OVER(PARTITION BY b.VesselCode,b.VoyageNo)
FROM POSITIONBOOK b
where b.VesselCode = a.VesselCode AND b.VoyageNo = a.VoyageNo
AND b.ArrivalDate>SYSDATE
AND ROWNUM=1
) AS NextETA
,a.STATUS VoyageStatus
,a.Trade
,UFN_MyVoyConcatinate_Values('FIXNOTE', a.VesselCode, a.VoyageNo) FixNote
,UFN_MyVoyConcatinate_Values('CHARTERER', a.VesselCode, a.VoyageNo) Charterer
,CASE WHEN st.CurrentStatus=0
THEN 1
WHEN st.CurrentStatus=1
THEN 0
ELSE st.CurrentStatus
END AS CurrentStatus
FROM Positionbook a
JOIN deftbl c
ON a.VesselCode = c.VesselCode
AND a.VoyageNo = c.VoyageNo
JOIN Vessel v
ON v.Code = c.VesselCode
LEFT JOIN GTT_VOYAGESTATUS st
ON st.VesselCode = c.Vesselcode
AND st.VoyageNo = c.VoyageNo
GROUP BY a.VesselCode
, v.Name
, a.VoyageNo
, c.StartOfVoyage
, c.EndOfVoyage
/*, a.FROMPORT
, a.TOPORT*/
, a.Status
, a.Trade
, st.CurrentStatus;
Note:
i changed the function without pipelined also. but it doesnt show much difference
non pipelined function
CREATE OR REPLACE FUNCTION TF_ShiporShipTypeByUser_nonp
In_UserName IN VARCHAR2,
In_Type IN VARCHAR2,
In_VesselCode IN VARCHAR2,
In_CompanyHistory IN NUMBER DEFAULT 0
RETURN str_array AS
l_ShipTypeUser NUMBER(10,0);
l_CompanyUser NUMBER(10,0);
l_UseCompanyHistory NUMBER(1,0);
l_Snicsacct NUMBER(1,0);
l_str_array str_array:=str_array();
BEGIN
BEGIN
SELECT shiptype_user,
company_user
INTO l_ShipTypeUser,
l_CompanyUser
FROM User_Segregation;
EXCEPTION
WHEN OTHERS THEN
l_ShipTypeUser := NULL;
l_CompanyUser := NULL;
END;
BEGIN
SELECT 1 INTO l_Snicsacct
FROM DUAL
WHERE NOT EXISTS ( SELECT 1 FROM sn_user_cfg WHERE UserID='SNICS' and CfgID='ACCTSYS');
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
IF In_CompanyHistory = 1
THEN
BEGIN
SELECT CfgData
INTO l_UseCompanyHistory
FROM SN_User_Cfg
WHERE CfgID = 'USE COMPANY HISTORY'
AND UserID = 'SNICS';
EXCEPTION
WHEN OTHERS THEN
l_UseCompanyHistory := 0;
END;
END IF;
IF In_UserName = 'SYSADM' OR (l_CompanyUser = 0 AND l_ShipTypeUser = 0)
OR (l_CompanyUser = 1 and l_Snicsacct =1 ) or (In_CompanyHistory = 0 and l_CompanyUser = 1 and In_Type ='ShipType')
OR (l_ShipTypeUser = 1 and In_Type = 'Company')
THEN
BEGIN
IF In_Type = 'ShipType'
THEN
BEGIN
SELECT STR_TYPE(Code,1,999999999)
BULK COLLECT INTO l_str_array
FROM VesselType;
RETURN l_str_array;
END;
ELSIF In_Type = 'Ship'
THEN
BEGIN
SELECT STR_TYPE(SKIPS_KODE,1,999999999)
BULK COLLECT INTO l_str_array
FROM T065_SHIP
WHERE SKIPS_KODE = NVL(In_VesselCode,SKIPS_KODE);
RETURN l_str_array;
END;
ELSIF In_Type = 'Company'
THEN
BEGIN
SELECT STR_TYPE(SELSKAPSKODE,NULL,NULL)
BULK COLLECT INTO l_str_array
FROM SelsKap;
RETURN l_str_array;
END;
END IF;
END;
ELSE
IF In_Type = 'Ship'
THEN
BEGIN
IF l_ShipTypeUser =1
THEN
BEGIN
SELECT STR_TYPE(S.SKIPS_KODE,1,999999999)
BULK COLLECT INTO l_str_array
FROM T065_SHIP S
JOIN t041_shiptypeusers U
ON S.CODE_SHIPTYPE = U.Code_ShipType
AND USERID = In_UserName
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
GROUP BY S.SKIPS_KODE;
RETURN l_str_array;
END;
ELSIF l_CompanyUser = 1
THEN
BEGIN
IF l_UseCompanyHistory = 1 AND In_CompanyHistory = 1
THEN
SELECT STR_TYPE(ShipCode,VoyageFrom,VoyageTo)
BULK COLLECT INTO l_str_array
FROM ( SELECT a.VesselCode ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
JOIN T62_BRUKER_SELSKAP b
ON a.Company = b.SELSKAPSKODE
AND b.BRUKER = In_UserName
WHERE a.VesselCode = NVL(In_VesselCode, a.VesselCode)
UNION
SELECT a.VesselCode ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.company = b.SELSKAPSKODE
WHERE a.VesselCode = NVL(In_VesselCode, a.VesselCode)
AND b.SELSKAPSKODE IS NULL
GROUP BY a.VesselCode,
a.VoyageNo,
a.VoyageNo);
RETURN l_str_array;
ELSE
SELECT STR_TYPE(ShipCode,VoyageFrom,VoyageTo)
BULK COLLECT INTO l_str_array
FROM (SELECT a.SKIPS_KODE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP a
JOIN T62_BRUKER_SELSKAP b
ON a.Company = b.SELSKAPSKODE
AND b.BRUKER = In_UserName
WHERE a.SKIPS_KODE = NVL(In_VesselCode, a.SKIPS_KODE)
AND NVL(l_UseCompanyHistory,0) = 0
UNION
SELECT a.SKIPS_KODE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.company = b.SELSKAPSKODE
WHERE a.SKIPS_KODE = NVL(In_VesselCode, a.SKIPS_KODE)
AND b.SELSKAPSKODE IS NULL
GROUP BY a.SKIPS_KODE);
RETURN l_str_array;
END IF;
END;
END IF;
END;
ELSIF In_Type = 'ShipType'
THEN
IF l_ShipTypeUser = 1
THEN
BEGIN
SELECT STR_TYPE(ShipCode,VoyageFrom,VoyageTo)
BULK COLLECT INTO l_str_array
FROM (SELECT S.CODE_SHIPTYPE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP S
JOIN t041_shiptypeusers U
ON S.CODE_SHIPTYPE = U.Code_ShipType
AND USERID = In_UserName
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
GROUP BY S.CODE_SHIPTYPE);
RETURN l_str_array;
END;
ELSIF l_CompanyUser = 1
THEN
IF l_UseCompanyHistory = 1 AND In_CompanyHistory = 1
THEN
BEGIN
SELECT STR_TYPE(ShipCode,VoyageFrom,VoyageTo)
BULK COLLECT INTO l_str_array
FROM ( SELECT a.VesselType ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
JOIN T62_BRUKER_SELSKAP b
ON a.COMPANY = b.SELSKAPSKODE
AND b.BRUKER = In_UserName
WHERE a.VesselCode = NVL(In_VesselCode,a.VesselCode)
UNION
SELECT a.VesselType ShipCode
, a.VoyageNo VoyageFrom
, a.VoyageNo VoyageTo
FROM PositionBook a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.company = b.SELSKAPSKODE
WHERE a.VesselCode = NVL(In_VesselCode, a.VesselCode)
AND b.SELSKAPSKODE IS NULL
GROUP BY a.VesselType,
a.VoyageNo,
a.VoyageNo);
RETURN l_str_array;
END;
ELSE
BEGIN
SELECT STR_TYPE(ShipCode,VoyageFrom,VoyageTo)
BULK COLLECT INTO l_str_array
FROM ( SELECT S.CODE_SHIPTYPE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP S
JOIN T62_BRUKER_SELSKAP b
ON S.company = b.SELSKAPSKODE
AND B.BRUKER = In_UserName
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
AND NVL(l_UseCompanyHistory,0) = 0
UNION
SELECT S.CODE_SHIPTYPE ShipCode
, 1 VoyageFrom
, 999999999 VoyageTo
FROM T065_SHIP S
LEFT JOIN T62_BRUKER_SELSKAP b
ON S.company = b.SELSKAPSKODE
WHERE S.SKIPS_KODE = NVL(In_VesselCode, S.SKIPS_KODE)
AND b.SELSKAPSKODE IS NULL);
RETURN l_str_array;
END;
END IF;
END IF;
ELSIF In_Type = 'Company'
THEN
BEGIN
SELECT STR_TYPE(ShipCode,VoyageFrom,VoyageTo)
BULK COLLECT INTO l_str_array
FROM ( SELECT a.SELSKAPSKODE ShipCode
, NULL VoyageFrom
, NULL VoyageTo
FROM Selskap a
JOIN T62_BRUKER_SELSKAP b
ON a.SELSKAPSKODE = b.SELSKAPSKODE
WHERE b.BRUKER = In_UserName
Union All
Select a.SELSKAPSKODE ShipCode
, NULL VoyageFrom
, NULL VoyageTo
From Selskap a
LEFT JOIN T62_BRUKER_SELSKAP b
ON a.SELSKAPSKODE = b.SELSKAPSKODE
Where b.SELSKAPSKODE IS NULL
GROUP BY a.SELSKAPSKODE);
RETURN l_str_array;
END;
END IF;
END IF;
END;please kindly provide me your valuable suggestions
Edited by: ganex27lin on Mar 16, 2011 1:54 AM -
BC4J view objects on pipeline functions
Hello,
I just wanted to find out if we can place a BC4J view object on the new Oracle 9i Pipeline functions.
Thanks
RamnaIf it still looks on the outside like a database view to the JDBC client (BC4J in this case), then sure.
If you're making updates, then your underlying entity object will have to:
[list]
[*]Be mapped to an appropriate, updateable table, or
[*]Write INSTEAD OF triggers for your view
[list]
Let us know if you hit any problems. -
Using pipelined functions with bind variables in Apex...
Hy all:
I have a table which has about 10 million records and it is hanging up the system when it is trying to retrieve the data from that table... so what I have done is I created a pripelined
function and then trying to retrieve data using an SQL statement ... when I try to use a bind variable to filter by the date and location it is binding according to the location
but not by date ... can anyone help me in this please!!
Help greatly appreciated !
Thanks in advance !Hi Denes:
Create or replace type ohe1 as object (
IMLITM NCHAR(50), IMAITM NCHAR(50), IMDSC1 NCHAR(60), COUNCS NUMBER(22), LIPQOH NUMBER(22),
LIMCU NCHAR(24), LILOCN NCHAR(40), LILOTN NCHAR(60), LILOTS NCHAR(2), IOMMEJ NUMBER(22))
CREATE OR REPLACE TYPE OHE AS TABLE OF Ohe1
CREATE OR REPLACE FUNCTION GET_ohe
return OHE PIPELINED
IS
m_rec ohe1:= ohe1 (NULL,NULL,NULL,0,0,NULL,NULL,NULL,NULL,0);
begin
for c in (select f1.LITM LITM, F1.AITM AITM, F1.DSC1 DSC1, F5.UNCS UNCS,
F21.QOH QOH, F21.MCU MCU, F21.LOCN LOCN, F21.LOTN LOTN, F21.LOTS LOTS,
F8.MEJ MEJ FROM F1 F1, F2 F2, F21 F21, F5 F5, F8 F8
WHERE (F5.EDG='07') AND (F21.QOH != 0) AND F2.IBITM = F1.IMITM
AND F21.ITM = F2.ITM AND F21.ITM = F5.ITM AND F21.MCU = F5.MCU
AND F21.MCU = F2.MCU AND F21.LOTN = F8.LOTN AND F21.MCU = F8.MCU)
loop
m_rec.LITM:=c.LITM;
m_rec.AITM:=c.AITM;
m_rec.DSC1:=c.DSC1;
m_rec.UNCS:=c.UNCS;
my_record.QOH:=c.QOH;
my_record.MCU:=c.MCU;
my_record.LOCN:=c.LOCN;
my_record.LOTN:=c.LOTN;
my_record.LOTS:=c.LOTS;
my_record.MEJ:=c.MEJ;
PIPE ROW (my_record);
end loop;
return;
end;
select LITM , AITM , DSC1 , UNCS*.0001 UNCS, QOH*.0001 QOH, (UNCS*.0001)*(QOH*.0001) AMOUNT,
MCU MCU, LOCN LOCN, LOTN LOTN, LOTS LOTS, jdate(DECODE(MEJ,0,100001,MEJ)) MEJ FROM
TABLE (GET_ohe)
WHERE trim(LIMCU)= TRIM(:OHE_BRANCHID)
AND (jdate(DECODE(MEJ,0,10001,MEJ)) >=:FROMEXPDT
AND jdate(DECODE(MEJ,0,10001,MEJ)) <=:TOEXPDATE)
The MEJ is a julian date and I am trying to convert it into a date ..... using the function jdate! and the pipelined function is created without any errors
and I am able to get the data with correct branch location bind variable but only problem is it is not binding the date filters in the sql.....
Thanks
Edited by: user10183758 on Oct 16, 2008 8:17 AM
Maybe you are looking for
-
IMOVIE Text Not working?
I have Imovie and my text does not work. Every time i hit the text, IMOVIE starts to perform slowly and freeze up to the point i have to force quit. All the other buttons work (like the transitions, music, pictures) but not the text. I have no idea h
-
My own Google Map icons are not visible in Firefox 8
I have many Google Maps on my website and they contain both default Google icons and my own icons, each with their own URLs. They work correctly in all other browsers, and Firefox 7. However, yesterday I loaded Firefox 8. In Firefox 8 the Google defa
-
Can,t burn disk image or burn direct to DVD. He crash after learn theme he don't go to movie??? he crash after just 1 minutes??? before from 1 year never problem?? Solution please! Michel
-
[SQL SERVER 2000] Generic table exporter
Hello every body. First of all sorry for my bad english but I'm french ;-) My internship consits into making a generic table exporter (with a table list). Export into csv files. I have tried 2 solutions : 1 - Create a DTS with a Dynamic Properties Ta
-
My work-issued laptop doesn't allow me to upload files so it possible to convert a PDF file to Word bu just entering the URL of the document.I have a feeling this used to be feasible, Thanks