Bulk Collect in DBMS_SQL package
Dear all,
just wondering if DBMS_SQL can do "bulk collect into", since I cannot find such procedure that does it. Also what can I do is copying the DBMS_SQL cursor to a ref cursor then I can do the "bulk collect into". Is this the only way when the current cursor is using DBMS_SQL?
best regards,
Val
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/d_sql.htm#ARPLS68203
Similar Messages
-
Error while doing Bulk Collect to a table type
I'm using a Table type to accumulate resultset from a loop and finally return the records in the table type as a ref cursor to the front end.
But when I'm using Bult collect to insert into the table type object it keeps throwing an error
'PLS-00597: expression 'TAB_CALENDAR_AVAIL_RESULTSET' in the INTO list is of wrong type'. Can someone help me to let me know what could be the reason for this error. I'm not able to proceed further, please help.
Here is the code.
CREATE OR REPLACE PACKAGE hotel
AS
TYPE calendar_cursor IS REF CURSOR;
TYPE type_calendar_avail is RECORD(
HOTEL_ID AVAILABILITY_CALENDAR.hotel_id%TYPE,--varchar2(4), --AVAILABILITY_CALENDAR.hotel_id%TYPE,
AVAIL_DATE AVAILABILITY_CALENDAR.AVAIL_DATE%TYPE ,
TOTAL_COUNT number
TYPE type_calendar_avail_resultset IS TABLE OF type_calendar_avail;
tab_calendar_avail_resultset type_calendar_avail_resultset ; -- declare variable of type type_calendar_avail_resultset
PROCEDURE sp_get_calendar_results (
sallhotelswithavaildate VARCHAR2,
ilengthofstay NUMBER,
sorcowner VARCHAR2,
all_unittypes VARCHAR2, --DBMS_SQL.VARCHAR2S
calendar_resultset OUT calendar_cursor
-- tab_calendar_avail_resultset out type_calendar_avail_resultset
PROCEDURE sp_get_calendar_results (
sallhotelswithavaildate VARCHAR2,
ilengthofstay NUMBER,
-- ivariant NUMBER,
sorcowner VARCHAR2,
all_unittypes VARCHAR2, --DBMS_SQL.VARCHAR2S
calendar_resultset OUT calendar_cursor
AS
sbuf VARCHAR2 (200);
sepr VARCHAR2 (1);
shotelwithdate VARCHAR2 (200);
shotelid VARCHAR2 (10);
savaildate VARCHAR2 (8);
sactualavaildate VARCHAR2 (8);
pos NUMBER;
istart NUMBER;
sstartdate VARCHAR2 (8);
senddate VARCHAR2 (8);
squery VARCHAR2 (32767) := '';
sunittypecond VARCHAR2 (500) := '';
sunitdesccond VARCHAR2 (500) := '';
v_unit_cond a_unit_cond;
tempunitcond VARCHAR2 (50) := '';
BEGIN
istart := 1;
LOOP
tempunitcond := hotel.stringtokenizer (all_unittypes, istart, '|');
IF tempunitcond IS NOT NULL
THEN
v_unit_cond (istart) := tempunitcond;
istart := istart + 1;
END IF;
EXIT WHEN tempunitcond IS NULL;
END LOOP;
sunitdesccond := hotel.get_unit_description_cond (v_unit_cond);
DBMS_OUTPUT.put_line ('unit description : ' || sunitdesccond);
sbuf := sallhotelswithavaildate;
sepr := '|';
istart := 1;
LOOP
shotelwithdate := hotel.stringtokenizer (sbuf, istart, sepr);
EXIT WHEN shotelwithdate IS NULL;
shotelid :=
SUBSTR (shotelwithdate, 1, INSTR (shotelwithdate, ',') - 1);
savaildate :=
SUBSTR (shotelwithdate, INSTR (shotelwithdate, ',') + 1);
squery :=
' SELECT MIN (ad.avail_date) '
|| ' FROM wvo_fonres.fpavail_daily ad'
|| ' WHERE ad.hotel_id = '
|| shotelid
|| ' AND ad.days_left >= '
|| ilengthofstay
|| ' AND ad.avail_date >= '
|| savaildate;
IF UPPER (sorcowner) = 'N'
THEN
squery :=
squery
|| ' AND ad.ORC_TYPE != ''R'' and ad.ORC_TYPE != ''P'' and ad.ORC_TYPE != ''E'' ';
END IF;
squery := squery || ' AND ( ' || sunitdesccond || ') ';
EXECUTE IMMEDIATE squery
INTO sactualavaildate;
DBMS_OUTPUT.put_line ('Actual available Date: ' || sactualavaildate);
hotel.sp_get_startdate_enddate (sactualavaildate,
--ivariant,
sstartdate,
senddate
sunittypecond := hotel.get_unittype_cond (v_unit_cond, sorcowner);
-- execute immediate
squery :=
'select HOTEL_ID, AVAIL_DATE, ' || sunittypecond || ' AS TOTAL_COUNT '
|| ' FROM AVAILABILITY_CALENDAR A '
|| 'WHERE '
|| 'AVAIL_DATE >= '''
|| sstartdate
|| ''' '
|| 'AND '
|| 'AVAIL_DATE <= '''
|| senddate
|| ''' '
||'AND '
|| 'A.HOTEL_ID IN ('
|| shotelid
|| ') '
|| 'AND ('
|| sunittypecond
|| '> 0) '
|| -- where total available count of unit type is greater than 0
' ORDER BY AVAIL_DATE'; --order clause
open calendar_resultset for squery;
fetch calendar_resultset BULK COLLECT INTO tab_calendar_avail_resultset;
istart := istart + 1;
END LOOP;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line
(SQLERRM (SQLCODE));
RAISE;
END sp_get_calendar_results;
END hotel;
/1. put tags [co[/b][b]de] and [co[/b][b]de] around your code, so it's readable
B. what does "hotel.get_unittype_cond (v_unit_cond, sorcowner)" actually retun?
and third, try this for the array declaration:
tab_calendar_avail_resultset type_calendar_avail_resultset := type_calendar_avail_resultset ; () ; -
Bulk collect into using vector in where clause
Hi,
I have a java stored procedure which takes an array as input and returns an array as output.
I want to select a column in to a collection of array, using array as the select criteria.
For example
create or replace type My_list as table of varchar(20);
create or replace type outarray as table of BLOB;
create or replace function myfunction ( inputlist My_list)
return outarray
AS
o_data := outarray();
BEGIN
SELECT mycolumn from mytable BULK COLLECT INTO o_data where my_creteria=inputlist
retrun o_data;
END;
Unless I use FORALL I can not retrieve the inputlist values. I am not sure how I can use the bulk collect and forall in the same statement?
My data is arranged such that , for each value in the inputlist one row will be fetched. I want to fetch all these rows at one go using the inputlist as select criteria,
I can use the for i in inputlist.first .. inputlist.LAST and iterate the inputlist but that process is quite expensive interms of the latency.
You help in optimizing my query would be highly appreciated.
Regards,
SyamThat only leaves ugly solutions, like:
<ul>
<li>Using dynamic SQL to create a temporary table, doing a bulk insert of the incoming array and then reading the table values using a subquery with the IN opeartor.</li>
<li>Building a dyanmic list, like ('value1','value2', ..) and use it with the IN operator, this is a variable list and requires DBMS_SQL package.</li>
<li>Ignore the bulk operations. :-(</li>
</ul> -
Bulk collect limit 1000 is looping only 1000 records out of 35000 records
In below code I have to loop around 35000 records for every month of the year starting from Aug-2010 to Aug-2011.
I am using bulk collect with limit clause but the problem is:
a: Limit clause is returning only 1000 records.
b: It is taking too much time to process.
CREATE OR REPLACE PACKAGE BODY UDBFINV AS
F UTL_FILE.FILE_TYPE;
PV_SEQ_NO NUMBER(7);
PV_REC_CNT NUMBER(7) := 0;
PV_CRLF VARCHAR2(2) := CHR(13) || CHR(10);
TYPE REC_PART IS RECORD(
PART_NUM PM_PART_HARSH.PART_NUM%TYPE,
ON_HAND_QTY PM_PART_HARSH.ON_HAND_QTY%TYPE,
ENGG_PREFIX PM_PART_HARSH.ENGG_PREFIX%TYPE,
ENGG_BASE PM_PART_HARSH.ENGG_BASE%TYPE,
ENGG_SUFFIX PM_PART_HARSH.ENGG_SUFFIX%TYPE);
TYPE TB_PART IS TABLE OF REC_PART;
TYPE REC_DATE IS RECORD(
START_DATE DATE,
END_DATE DATE);
TYPE TB_MONTH IS TABLE OF REC_DATE;
PROCEDURE MAIN IS
/* To be called in Scheduler Programs Action */
BEGIN
/* Initializing package global variables;*/
IFMAINT.V_PROG_NAME := 'FULL_INVENTORY';
IFMAINT.V_ERR_LOG_TAB := 'UDB_ERR_FINV';
IFMAINT.V_HIST_TAB := 'UDB_HT_FINV';
IFMAINT.V_UTL_DIR_NAME := 'UDB_SEND';
IFMAINT.V_PROG_TYPE := 'S';
IFMAINT.V_IF_TYPE := 'U';
IFMAINT.V_REC_CNT := 0;
IFMAINT.V_DEL_INS := 'Y';
IFMAINT.V_KEY_INFO := NULL;
IFMAINT.V_MSG := NULL;
IFMAINT.V_ORA_MSG := NULL;
IFSMAINT.V_FILE_NUM := IFSMAINT.V_FILE_NUM + 1;
IFMAINT.LOG_ERROR; /*Initialize error log table, delete prev. rows*/
/*End of initialization section*/
IFMAINT.SET_INITIAL_PARAM;
IFMAINT.SET_PROGRAM_PARAM;
IFMAINT.SET_UTL_DIR_PATH;
IFMAINT.GET_DEALER_PARAMETERS;
PV_SEQ_NO := IFSMAINT.GENERATE_FILE_NAME;
IF NOT CHECK_FILE_EXISTS THEN
WRITE_FILE;
END IF;
IF IFMAINT.V_BACKUP_PATH_SEND IS NOT NULL THEN
IFMAINT.COPY_FILE(IFMAINT.V_UTL_DIR_PATH,
IFMAINT.V_FILE_NAME,
IFMAINT.V_BACKUP_PATH_SEND);
END IF;
IFMAINT.MOVE_FILE(IFMAINT.V_UTL_DIR_PATH,
IFMAINT.V_FILE_NAME,
IFMAINT.V_FILE_DEST_PATH);
COMMIT;
EXCEPTION
WHEN IFMAINT.E_TERMINATE THEN
IFMAINT.V_DEL_INS := 'N';
IFMAINT.LOG_ERROR;
ROLLBACK;
UTL_FILE.FCLOSE(F);
IFMAINT.DELETE_FILE(IFMAINT.V_UTL_DIR_PATH, IFMAINT.V_FILE_NAME);
RAISE_APPLICATION_ERROR(IFMAINT.V_USER_ERRCODE, IFMAINT.V_ORA_MSG);
WHEN OTHERS THEN
IFMAINT.V_DEL_INS := 'N';
IFMAINT.V_MSG := 'ERROR IN MAIN PROCEDURE ||IFMAINT.V_PROG_NAME';
IFMAINT.V_ORA_MSG := SUBSTR(SQLERRM, 1, 255);
IFMAINT.V_USER_ERRCODE := -20101;
IFMAINT.LOG_ERROR;
ROLLBACK;
UTL_FILE.FCLOSE(F);
IFMAINT.DELETE_FILE(IFMAINT.V_UTL_DIR_PATH, IFMAINT.V_FILE_NAME);
RAISE_APPLICATION_ERROR(IFMAINT.V_USER_ERRCODE, IFMAINT.V_ORA_MSG);
END;
PROCEDURE WRITE_FILE IS
CURSOR CR_PART IS
SELECT A.PART_NUM, ON_HAND_QTY, ENGG_PREFIX, ENGG_BASE, ENGG_SUFFIX
FROM PM_PART_HARSH A;
lv_cursor TB_PART;
LV_CURR_MONTH NUMBER;
LV_MONTH_1 NUMBER := NULL;
LV_MONTH_2 NUMBER := NULL;
LV_MONTH_3 NUMBER := NULL;
LV_MONTH_4 NUMBER := NULL;
LV_MONTH_5 NUMBER := NULL;
LV_MONTH_6 NUMBER := NULL;
LV_MONTH_7 NUMBER := NULL;
LV_MONTH_8 NUMBER := NULL;
LV_MONTH_9 NUMBER := NULL;
LV_MONTH_10 NUMBER := NULL;
LV_MONTH_11 NUMBER := NULL;
LV_MONTH_12 NUMBER := NULL;
lv_month TB_MONTH := TB_MONTH();
BEGIN
IF CR_PART%ISOPEN THEN
CLOSE CR_PART;
END IF;
FOR K IN 1 .. 12 LOOP
lv_month.EXTEND();
lv_month(k).start_date := ADD_MONTHS(TRUNC(SYSDATE, 'MM'), - (K + 1));
lv_month(k).end_date := (ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -K) - 1);
END LOOP;
F := utl_file.fopen(IFMAINT.V_UTL_DIR_NAME, IFMAINT.V_FILE_NAME, 'W');
IF UTL_FILE.IS_OPEN(F) THEN
/*FILE HEADER*/
utl_file.put_line(F,
RPAD('$CUD-', 5, ' ') ||
RPAD(SUBSTR(IFMAINT.V_PANDA_CD, 1, 5), 5, ' ') ||
RPAD('-136-', 5, ' ') || RPAD('000000', 6, ' ') ||
RPAD('-REDFLEX-KA-', 13, ' ') ||
RPAD('00000000-', 9, ' ') ||
RPAD(IFMAINT.V_CDS_SPEC_REL_NUM, 5, ' ') ||
RPAD('CD', 2, ' ') ||
RPAD(TO_CHAR(SYSDATE, 'MMDDYY'), 6, ' ') ||
LPAD(IFSMAINT.V_FILE_NUM, 2, 0) ||
RPAD('-', 1, ' ') || RPAD(' ', 9, ' ') ||
RPAD('-', 1, ' ') || RPAD(' ', 17, ' ') ||
RPAD('CD230', 5, ' ') ||
RPAD(TO_CHAR(SYSDATE, 'MMDDYY'), 6, ' ') ||
LPAD(IFSMAINT.V_FILE_NUM, 2, 0) ||
LPAD(PV_REC_CNT, 8, 0) || RPAD(' ', 5, ' ') ||
RPAD('00000000', 8, ' ') || RPAD('CUD', 3, ' ') ||
RPAD(IFMAINT.V_CDS_SPEC_REL_NUM, 5, ' ') ||
RPAD(IFMAINT.V_GEO_SALES_AREA_CD, 3, ' ') ||
RPAD(IFMAINT.V_FRANCHISE_CD, 2, ' ') ||
RPAD(IFMAINT.V_DSP_REL_NUM, 9, ' ') ||
RPAD('00136REDFLEX', 12, ' ') || RPAD(' ', 1, ' ') ||
RPAD('KA', 2, ' ') || RPAD('000000', 6, ' ') ||
RPAD('00D', 3, ' ') ||
RPAD(IFMAINT.V_VENDOR_ID, 6, ' ') ||
RPAD(IFSMAINT.V_FILE_TYPE, 1, ' ') ||
RPAD('>', 1, ' ') || PV_CRLF);
/*LINE ITEMS*/
OPEN CR_PART;
FETCH CR_PART BULK COLLECT
INTO lv_cursor limit 1000;
FOR I IN lv_cursor.FIRST .. lv_cursor.LAST LOOP
SELECT SUM(A.BILL_QTY)
INTO LV_CURR_MONTH
FROM PD_ISSUE A, PH_ISSUE B
WHERE A.DOC_TYPE IN ('CRI', 'RRI', 'RSI', 'CSI')
AND A.DOC_NUM = B.DOC_NUM
AND B.DOC_DATE BETWEEN TRUNC(SYSDATE, 'MM') AND SYSDATE
AND A.PART_NUM = LV_CURSOR(i).PART_NUM;
FOR J IN 1 .. 12 LOOP
SELECT SUM(A.BILL_QTY)
INTO LV_MONTH_1
FROM PD_ISSUE A, PH_ISSUE B
WHERE A.DOC_TYPE IN ('CRI', 'RRI', 'RSI', 'CSI')
AND A.DOC_NUM = B.DOC_NUM
AND B.DOC_DATE BETWEEN lv_month(J).start_date and lv_month(J)
.end_date
AND A.PART_NUM = LV_CURSOR(i).PART_NUM;
END LOOP;
utl_file.put_line(F,
RPAD('IL', 2, ' ') ||
RPAD(TO_CHAR(SYSDATE, 'RRRRMMDD'), 8, ' ') ||
RPAD(LV_CURSOR(I).ENGG_PREFIX, 6, ' ') ||
RPAD(LV_CURSOR(I).ENGG_BASE, 8, ' ') ||
RPAD(LV_CURSOR(I).ENGG_SUFFIX, 6, ' ') ||
LPAD(LV_CURSOR(I).ON_HAND_QTY, 7, 0) ||
LPAD(NVL(LV_CURR_MONTH, 0), 7, 0) ||
LPAD(LV_MONTH_1, 7, 0) || LPAD(LV_MONTH_2, 7, 0) ||
LPAD(LV_MONTH_3, 7, 0) || LPAD(LV_MONTH_4, 7, 0) ||
LPAD(LV_MONTH_5, 7, 0) || LPAD(LV_MONTH_6, 7, 0) ||
LPAD(LV_MONTH_7, 7, 0) || LPAD(LV_MONTH_8, 7, 0) ||
LPAD(LV_MONTH_9, 7, 0) || LPAD(LV_MONTH_10, 7, 0) ||
LPAD(LV_MONTH_11, 7, 0) ||
LPAD(LV_MONTH_12, 7, 0));
IFMAINT.V_REC_CNT := IFMAINT.V_REC_CNT + 1;
END LOOP;
CLOSE CR_PART;
/*TRAILER*/
utl_file.put_line(F,
RPAD('$EOF-', 5, ' ') || RPAD('320R', 4, ' ') ||
RPAD(SUBSTR(IFMAINT.V_PANDA_CD, 1, 5), 5, ' ') ||
RPAD(' ', 5, ' ') ||
RPAD(IFMAINT.V_GEO_SALES_AREA_CD, 3, ' ') ||
RPAD(TO_CHAR(SYSDATE, 'MM-DD-RR'), 6, ' ') ||
LPAD(IFSMAINT.V_FILE_NUM, 2, 0) ||
LPAD(IFMAINT.V_REC_CNT, 8, 0) || 'H' || '>' ||
IFMAINT.V_REC_CNT);
utl_file.fclose(F);
IFMAINT.INSERT_HISTORY;
END IF;
END;
FUNCTION CHECK_FILE_EXISTS RETURN BOOLEAN IS
LB_FILE_EXIST BOOLEAN := FALSE;
LN_FILE_LENGTH NUMBER;
LN_BLOCK_SIZE NUMBER;
BEGIN
UTL_FILE.FGETATTR(IFMAINT.V_UTL_DIR_NAME,
IFMAINT.V_FILE_NAME,
LB_FILE_EXIST,
LN_FILE_LENGTH,
LN_BLOCK_SIZE);
IF LB_FILE_EXIST THEN
RETURN TRUE;
END IF;
RETURN FALSE;
EXCEPTION
WHEN OTHERS THEN
RETURN FALSE;
END;
END;Try this:
OPEN CR_PART;
loop
FETCH CR_PART BULK COLLECT
INTO lv_cursor limit 1000;
exit when CR_PART%notfound;
FOR I IN lv_cursor.FIRST .. lv_cursor.LAST LOOP
SELECT SUM(A.BILL_QTY)
INTO LV_CURR_MONTH
FROM PD_ISSUE A, PH_ISSUE B
WHERE A.DOC_TYPE IN ('CRI', 'RRI', 'RSI', 'CSI')
AND A.DOC_NUM = B.DOC_NUM
AND B.DOC_DATE BETWEEN TRUNC(SYSDATE, 'MM') AND SYSDATE
AND A.PART_NUM = LV_CURSOR(i).PART_NUM;
FOR J IN 1 .. 12 LOOP
SELECT SUM(A.BILL_QTY)
INTO LV_MONTH_1
FROM PD_ISSUE A, PH_ISSUE B
WHERE A.DOC_TYPE IN ('CRI', 'RRI', 'RSI', 'CSI')
AND A.DOC_NUM = B.DOC_NUM
AND B.DOC_DATE BETWEEN lv_month(J).start_date and lv_month(J)
.end_date
AND A.PART_NUM = LV_CURSOR(i).PART_NUM;
END LOOP;
utl_file.put_line(F,
RPAD('IL', 2, ' ') ||
RPAD(TO_CHAR(SYSDATE, 'RRRRMMDD'), 8, ' ') ||
RPAD(LV_CURSOR(I).ENGG_PREFIX, 6, ' ') ||
RPAD(LV_CURSOR(I).ENGG_BASE, 8, ' ') ||
RPAD(LV_CURSOR(I).ENGG_SUFFIX, 6, ' ') ||
LPAD(LV_CURSOR(I).ON_HAND_QTY, 7, 0) ||
LPAD(NVL(LV_CURR_MONTH, 0), 7, 0) ||
LPAD(LV_MONTH_1, 7, 0) || LPAD(LV_MONTH_2, 7, 0) ||
LPAD(LV_MONTH_3, 7, 0) || LPAD(LV_MONTH_4, 7, 0) ||
LPAD(LV_MONTH_5, 7, 0) || LPAD(LV_MONTH_6, 7, 0) ||
LPAD(LV_MONTH_7, 7, 0) || LPAD(LV_MONTH_8, 7, 0) ||
LPAD(LV_MONTH_9, 7, 0) || LPAD(LV_MONTH_10, 7, 0) ||
LPAD(LV_MONTH_11, 7, 0) ||
LPAD(LV_MONTH_12, 7, 0));
IFMAINT.V_REC_CNT := IFMAINT.V_REC_CNT + 1;
END LOOP;
end loop;
CLOSE CR_PART; -
I understand that Oracle 10g will rewrite your CURSOR FOR LOOP statements into a BULK COLLECT statement.
I am contemplating no longer explicitly writing the BULK COLLECT from now on as it reduces the number of lines of code and greatly simplifies code.
Can anyone see any serious flaws in this strategy?
Kind Regards
Chris> I also think it is a good idea if people do take the
time to decide their strategy. You seem to be
suggesting that it is a bad idea to stop and think
about what you require from your loop.
Well, that depends on the type of programmer. When one deals with programmers that are not true PL/SQL developers and view PL/SQL.. well, as some kind of inferior database language (compared to something like Java for example).. you want to have templates and stuff to enforce best practises.
> I also don't agree with the 'package tuning knob'.
Each query may have different requirements and, as
with most things in programming, fixing one thing can
have a negative effect on another. It is about the
only place where would not advocate constants.
You have a point - but even so, defining these as constants (even if it has to be inside the actual proc doing the bulk fetch, one per bulk fetch) make it a lot easier to maintain than having to search out the actual bulk fetch statements in the code.
> But i would suggest that analysis is performed on a
close-to-live enviroment with a production level
server, large body of test data and multiple users. I
think we agree on that point.
Yeah.. but the problem there is that I have never really seen such an environment. Usually due to costs. How do you for example duplicate a large RAC, terabytes of SAN space, 1000's of users, for use as a close-to-live enviroment?
The usual approach (by management) is to spend as little as possible on development and Q&A platforms. Which at times means that the performance of dev vs. production can vary a lot.
So we have to play the hand we're dealt with unfortunately.
> Hmmm cmegar and I have never once said "don't worry
about, PL/SQL does it for you".
Yes - of course not. I'm just rambling on in general describing the usual attitudes I see when it comes to features like this.
It is managable in small dev team, but larger ones.. not really. There this attitude is often previlant in my experience. The "silver bullet" bullet syndrome.
> Would you use the same argument with regard to unit
testing. There are not many pl/sql developers who
unit test but should that prevent me using the
technique?
Well.. to be honest, I do not think that a developer that writes at least some basic unit tests for his/her code can be called a developer.
> >[i]Relying on implicit features to "fix" code for
you negates a deeper and better understanding of the
language and what you writeI don't see how using an implicit bulk collect is
fixing code.
Which is why I put it in brackets - "fixing" ito making it more performant, or "fixing" it as a FOR loop contains DMLs that can be changed to FORALLs.
> Don't tell me you've never
updated older code to take advangate of a new
feature.
I can never stop the urge to refactor old code I'm working with. :-)
> >[i]I think of features as an implicit bulk collect
behind the scenes, as crutches for mediocre
programmers.I take it that statement is suggesting that cmedgar
and I are mediocre programmers? Not a nice way to end
an otherwise constructive argument.
How does that saying go? You claim the cloth that I cut? :-)
My sincere apologies to both you guys - I did not intend that statement to personal at all.
Besides, I'm usually more blunt than that what it comes to throwing personal insults around. ;-)
This statement was just a general observation going back to my early days of writing Cobol and Natural. Programmers at time do not seem to care about grokking the features and apply them correctly. Actually I want to say "most programmers" and "a lot of times", but then I would be accused of generalisation. ;-)
I simply find it very frustrating dealing with programmers that does not simply love to write code. Programmers that see it as a mere job.
Someone once said that he never starts out to write beautiful code. But when he is done and the code is not beautiful and elegant (and simple), he knows he has screwed up.
In my experience.. many programmers will not understand this. -
How to use bulk collect into clause
hi all,
i have requirement like this i want to change the query by passing the different table names in oracle database 10gr2.
like if i use first i pass the scott.emp table name select * from scott.emp;
then i want pass scott.dept table name select * from scott.dept;
using select * option in the select list.
how can i execute it.
give me any solution.
please reply....Hi,
i recently also ran into some serious trouble to make dynamic sql work.
It was about parallel pipelined function with strongly typed cursor (for "partition ... by hash(...)").
But in addition requiring dynamic SQL for the input to this cursor.
I couldn't make it work with execute immediate or something else.
So i used another way - I translated dynamic SQL into dynamically created static SQL:
1. create a base SQL data object type with abstract interface for code (e.g. some Execute() member function).
2. dynamically create a derived SQL data object type with concrete implementation of Execute() holding your "dynamic SQL" "in a static way"
3. delegate to Execute().
Let me quote my example from comp.databases.oracle.server, thread "dynamically created cursor doesn't work for parallel pipelined functions"
- pls. see below (it's an old one - with likely some odd stuff inside).
It might sound some kind of strange for DB programmer.
(I come from C++. Though this is not an excuse smile)
Maybe i just missed another possible option to handle the problem.
And it's a definitely verbose.
But i think it's at least a (last) option.
Actually i would be interested to hear, what others think about it.
best regards,
Frank
--------------- snip -------------------------
drop table parallel_test;
drop type MyDoit;
drop type BaseDoit;
drop type ton;
create type ton as table of number;
CREATE TABLE parallel_test (
id NUMBER(10),
description VARCHAR2(50)
BEGIN
FOR i IN 1 .. 100000 LOOP
INSERT INTO parallel_test (id, description)
VALUES (i, 'Description or ' || i);
END LOOP;
COMMIT;
END;
create or replace type BaseDoit as object (
id number,
static function make(p_id in number)
return BaseDoit,
member procedure doit(
p_sids in out nocopy ton,
p_counts in out nocopy ton)
) not final;
create or replace type body BaseDoit as
static function make(p_id in number)
return BaseDoit
is
begin
return new BaseDoit(p_id);
end;
member procedure doit(
p_sids in out nocopy ton,
p_counts in out nocopy ton)
is
begin
dbms_output.put_line('BaseDoit.doit(' || id || ') invoked...');
end;
end;
-- Define a strongly typed REF CURSOR type.
CREATE OR REPLACE PACKAGE parallel_ptf_api AS
TYPE t_parallel_test_row IS RECORD (
id1 NUMBER(10),
desc1 VARCHAR2(50),
id2 NUMBER(10),
desc2 VARCHAR2(50),
sid NUMBER
TYPE t_parallel_test_tab IS TABLE OF t_parallel_test_row;
TYPE t_parallel_test_ref_cursor IS REF CURSOR RETURN
t_parallel_test_row;
FUNCTION test_ptf (p_cursor IN t_parallel_test_ref_cursor)
RETURN t_parallel_test_tab PIPELINED
PARALLEL_ENABLE(PARTITION p_cursor BY any);
END parallel_ptf_api;
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY parallel_ptf_api AS
FUNCTION test_ptf (p_cursor IN t_parallel_test_ref_cursor)
RETURN t_parallel_test_tab PIPELINED
PARALLEL_ENABLE(PARTITION p_cursor BY any)
IS
l_row t_parallel_test_row;
BEGIN
LOOP
FETCH p_cursor
INTO l_row;
EXIT WHEN p_cursor%NOTFOUND;
select userenv('SID') into l_row.sid from dual;
PIPE ROW (l_row);
END LOOP;
RETURN;
END test_ptf;
END parallel_ptf_api;
SHOW ERRORS
PROMPT
PROMPT Serial Execution
PROMPT ================
SELECT sid, count(*)
FROM TABLE(parallel_ptf_api.test_ptf(CURSOR(SELECT t1.id,
t1.description, t2.id, t2.description, null
FROM parallel_test t1,
parallel_test t2
where t1.id = t2.id
) t2
GROUP BY sid;
PROMPT
PROMPT Parallel Execution
PROMPT ==================
SELECT sid, count(*)
FROM TABLE(parallel_ptf_api.test_ptf(CURSOR(SELECT /*+
parallel(t1,5) */ t1.id, t1.description, t2.id, t2.description, null
FROM parallel_test t1,
parallel_test t2
where t1.id = t2.id
) t2
GROUP BY sid;
PROMPT
PROMPT Parallel Execution 2
PROMPT ==================
set serveroutput on;
declare
v_sids ton := ton();
v_counts ton := ton();
-- v_cur parallel_ptf_api.t_parallel_test_ref_cursor;
v_cur sys_refcursor;
procedure OpenCursor(p_refCursor out sys_refcursor)
is
begin
open p_refCursor for 'SELECT /*+ parallel(t1,5) */ t1.id,
t1.description, t2.id, t2.description, null
FROM parallel_test t1,
parallel_test t2
where t1.id = t2.id';
end;
begin
OpenCursor(v_cur);
SELECT sid, count(*) bulk collect into v_sids, v_counts
FROM TABLE(parallel_ptf_api.test_ptf(v_cur)) t2
GROUP BY sid;
for i in v_sids.FIRST.. v_sids.LAST loop
dbms_output.put_line (v_sids(i) || ', ' || v_counts(i));
end loop;
end;
PROMPT
PROMPT Parallel Execution 3
PROMPT ==================
set serveroutput on;
declare
instance BaseDoit;
v_sids ton := ton();
v_counts ton := ton();
procedure CreateMyDoit
is
cmd varchar2(4096 char);
begin
cmd := 'create or replace type MyDoit under BaseDoit ( ' ||
' static function make(p_id in number) ' ||
' return MyDoit, ' ||
' overriding member procedure doit( ' ||
' p_sids in out nocopy ton, ' ||
' p_counts in out nocopy ton) ' ||
execute immediate cmd;
cmd := 'create or replace type body MyDoit as ' ||
' static function make(p_id in number) ' ||
' return MyDoit ' ||
' is ' ||
' begin ' ||
' return new MyDoit(p_id); ' ||
' end; ' ||
' ' ||
' overriding member procedure doit( ' ||
' p_sids in out nocopy ton, ' ||
' p_counts in out nocopy ton) ' ||
' is ' ||
' begin ' ||
' dbms_output.put_line(''MyDoit.doit('' || id || '')
invoked...''); ' ||
' SELECT sid, count(*) bulk collect into p_sids, p_counts ' ||
' FROM TABLE(parallel_ptf_api.test_ptf(CURSOR( ' ||
' SELECT /*+ parallel(t1,5) */ t1.id, t1.description,
t2.id, t2.description, null ' ||
' FROM parallel_test t1, parallel_test t2 ' ||
' where t1.id = t2.id ' ||
' ))) ' ||
' GROUP BY sid; ' ||
' end; ' ||
' end; ';
execute immediate cmd;
end;
begin
CreateMyDoit;
execute immediate 'select MyDoit.Make(11) from dual' into instance;
instance.doit(v_sids, v_counts);
if v_sids.COUNT > 0 then
for i in v_sids.FIRST.. v_sids.LAST loop
dbms_output.put_line (v_sids(i) || ', ' || v_counts(i));
end loop;
end if;
end;
--------------- snap ------------------------- -
How to use BULK COLLECT, FORALL and TREAT
There is a need to read match and update data from and into a custom table. The table would have about 3 millions rows and holds key numbers. BAsed on a field value of this custom table, relevant data needs to be fetched from joins of other tables and updated in the custom table. I plan to use BULK COLLECT and FORALL.
All examples I have seen, do an insert into a table. How do I go about reading all values of a given field and fetching other relevant data and then updating the custom table with data fetched.
Defined an object with specifics like this
CREATE OR REPLACE TYPE imei_ot AS OBJECT (
recid NUMBER,
imei VARCHAR2(30),
STORE VARCHAR2(100),
status VARCHAR2(1),
TIMESTAMP DATE,
order_number VARCHAR2(30),
order_type VARCHAR2(30),
sku VARCHAR2(30),
order_date DATE,
attribute1 VARCHAR2(240),
market VARCHAR2(240),
processed_flag VARCHAR2(1),
last_update_date DATE
Now within a package procedure I have defined like this.
type imei_ott is table of imei_ot;
imei_ntt imei_ott;
begin
SELECT imei_ot (recid,
imei,
STORE,
status,
TIMESTAMP,
order_number,
order_type,
sku,
order_date,
attribute1,
market,
processed_flag,
last_update_date
BULK COLLECT INTO imei_ntt
FROM (SELECT stg.recid, stg.imei, cip.store_location, 'S',
co.rtl_txn_timestamp, co.rtl_order_number, 'CUST',
msi.segment1 || '.' || msi.segment3,
TRUNC (co.txn_timestamp), col.part_number, 'ZZ',
stg.processed_flag, SYSDATE
FROM custom_orders co,
custom_order_lines col,
custom_stg stg,
mtl_system_items_b msi
WHERE co.header_id = col.header_id
AND msi.inventory_item_id = col.inventory_item_id
AND msi.organization_id =
(SELECT organization_id
FROM hr_all_organization_units_tl
WHERE NAME = 'Item Master'
AND source_lang = USERENV ('LANG'))
AND stg.imei = col.serial_number
AND stg.processed_flag = 'U');
/* Update staging table in one go for COR order data */
FORALL indx IN 1 .. imei_ntt.COUNT
UPDATE custom_stg
SET STORE = TREAT (imei_ntt (indx) AS imei_ot).STORE,
status = TREAT (imei_ntt (indx) AS imei_ot).status,
TIMESTAMP = TREAT (imei_ntt (indx) AS imei_ot).TIMESTAMP,
order_number = TREAT (imei_ntt (indx) AS imei_ot).order_number,
order_type = TREAT (imei_ntt (indx) AS imei_ot).order_type,
sku = TREAT (imei_ntt (indx) AS imei_ot).sku,
order_date = TREAT (imei_ntt (indx) AS imei_ot).order_date,
attribute1 = TREAT (imei_ntt (indx) AS imei_ot).attribute1,
market = TREAT (imei_ntt (indx) AS imei_ot).market,
processed_flag =
TREAT (imei_ntt (indx) AS imei_ot).processed_flag,
last_update_date =
TREAT (imei_ntt (indx) AS imei_ot).last_update_date
WHERE recid = TREAT (imei_ntt (indx) AS imei_ot).recid
AND imei = TREAT (imei_ntt (indx) AS imei_ot).imei;
DBMS_OUTPUT.put_line ( TO_CHAR (SQL%ROWCOUNT)
|| ' rows updated using Bulk Collect / For All.'
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line ('No Data: ' || SQLERRM);
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Other Error: ' || SQLERRM);
END;
Now for the unfortunate part. When I compile the pkg, I face an error
PL/SQL: ORA-00904: "LAST_UPDATE_DATE": invalid identifier
I am not sure where I am wrong. Object type has the last update date field and the custom table also has the same field.
Could someone please throw some light and suggestion?
Thanks
udsI suspect your error comes from the »bulk collect into« and not from the »forall loop«.
From a first glance you need to alias sysdate with last_update_date and some of the other select items need to be aliased as well :
But a simplified version would be
select imei_ot (stg.recid,
stg.imei,
cip.store_location,
'S',
co.rtl_txn_timestamp,
co.rtl_order_number,
'CUST',
msi.segment1 || '.' || msi.segment3,
trunc (co.txn_timestamp),
col.part_number,
'ZZ',
stg.processed_flag,
sysdate
bulk collect into imei_ntt
from custom_orders co,
custom_order_lines col,
custom_stg stg,
mtl_system_items_b msi
where co.header_id = col.header_id
and msi.inventory_item_id = col.inventory_item_id
and msi.organization_id =
(select organization_id
from hr_all_organization_units_tl
where name = 'Item Master' and source_lang = userenv ('LANG'))
and stg.imei = col.serial_number
and stg.processed_flag = 'U';
... -
How to use Bulk Collect and Forall
Hi all,
We are on Oracle 10g. I have a requirement to read from table A and then for each record in table A, find matching rows in table B and then write the identified information in table B to the target table (table C). In the past, I had used two ‘cursor for loops’ to achieve that. To make the new procedure, more efficient, I would like to learn to use ‘bulk collect’ and ‘forall’.
Here is what I have so far:
DECLARE
TYPE employee_array IS TABLE OF EMPLOYEES%ROWTYPE;
employee_data employee_array;
TYPE job_history_array IS TABLE OF JOB_HISTORY%ROWTYPE;
Job_history_data job_history_array;
BatchSize CONSTANT POSITIVE := 5;
-- Read from File A
CURSOR c_get_employees IS
SELECT Employee_id,
first_name,
last_name,
hire_date,
job_id
FROM EMPLOYEES;
-- Read from File B based on employee ID in File A
CURSOR c_get_job_history (p_employee_id number) IS
select start_date,
end_date,
job_id,
department_id
FROM JOB_HISTORY
WHERE employee_id = p_employee_id;
BEGIN
OPEN c_get_employees;
LOOP
FETCH c_get_employees BULK COLLECT INTO employee_data.employee_id.LAST,
employee_data.first_name.LAST,
employee_data.last_name.LAST,
employee_data.hire_date.LAST,
employee_data.job_id.LAST
LIMIT BatchSize;
FORALL i in 1.. employee_data.COUNT
Open c_get_job_history (employee_data(i).employee_id);
FETCH c_get_job_history BULKCOLLECT INTO job_history_array LIMIT BatchSize;
FORALL k in 1.. Job_history_data.COUNT LOOP
-- insert into FILE C
INSERT INTO MY_TEST(employee_id, first_name, last_name, hire_date, job_id)
values (job_history_array(k).employee_id, job_history_array(k).first_name,
job_history_array(k).last_name, job_history_array(k).hire_date,
job_history_array(k).job_id);
EXIT WHEN job_ history_data.count < BatchSize
END LOOP;
CLOSE c_get_job_history;
EXIT WHEN employee_data.COUNT < BatchSize;
END LOOP;
COMMIT;
CLOSE c_get_employees;
END;
When I run this script, I get
[Error] Execution (47: 17): ORA-06550: line 47, column 17:
PLS-00103: Encountered the symbol "OPEN" when expecting one of the following:
. ( * @ % & - + / at mod remainder rem select update with
<an exponent (**)> delete insert || execute multiset save
merge
ORA-06550: line 48, column 17:
PLS-00103: Encountered the symbol "FETCH" when expecting one of the following:
begin function package pragma procedure subtype type use
<an identifier> <a double-quoted delimited-identifier> form
current cursorWhat is the best way to code this? Once, I learn how to do this, I apply the knowledge to the real application in which file A would have around 200 rows and file B would have hundreds of thousands of rows.
Thank you for your guidance,
SeyedHello BlueShadow,
Following your advice, I modified a stored procedure that initially was using two cursor for loops to read from tables A and B to write to table C to use instead something like your suggestion listed below:
INSERT INTO tableC
SELECT …
FROM tableA JOIN tableB on (join condition).I tried this change on a procedure writing to tableC with keys disabled. I will try this against the real table that has primary key and indexes and report the result later.
Thank you very much,
Seyed -
BULK COLLECT INTO (Oracle 11 G)
ORACLE 11G (The same code works fine in Oracle 9i)
FETCH v_cursor BULK COLLECT INTO AuditData, AuditData1;
the above statement gives me an error:-
ORA-01007: variable not in select list
ORA-06512: at "DEC0512.FCT_AUD_TRAIL_REAL_ENTRY_UPD", line 175
ORA-06512: at line 1
But if the change the statemement to
FETCH v_cursor BULK COLLECT INTO AuditData;
The query works fine.
Any help will be much appreciated.>
ORACLE 11G (The same code works fine in Oracle 9i)
FETCH v_cursor BULK COLLECT INTO AuditData, AuditData1;
the above statement gives me an error:-
ORA-01007: variable not in select list
ORA-06512: at "DEC0512.FCT_AUD_TRAIL_REAL_ENTRY_UPD", line 175
ORA-06512: at line 1
But if the change the statemement to
FETCH v_cursor BULK COLLECT INTO AuditData;
The query works fine.
Any help will be much appreciated.
>
If the second query 'works fine' then your 'AuditData' collection is consuming all of the result set columns and there is nothing to put into the other collection.
So you have a mismatch between the result set your cursor returns and those collections you are trying to put the data into.
This works for me:
DECLARE
CURSOR c1 IS (SELECT empno, deptno FROM emp);
empno_tab dbms_sql.number_table;
deptno_tab dbms_sql.number_table;
BEGIN
OPEN c1;
LOOP --Loop added
FETCH c1 BULK COLLECT INTO empno_tab, deptno_tab LIMIT 3; -- process 3 records at a time
-- process the first 3 records
DBMS_OUTPUT.PUT_LINE('Processing ' || empno_tab.COUNT || ' records.');
FOR i in 1..empno_tab.count loop
dbms_output.put_line('empno is [' || empno_tab(i) || '].');
end loop;
EXIT WHEN c1%NOTFOUND;
END LOOP;
DBMS_OUTPUT.PUT_LINE('All done');
END;
Processing 3 records.
empno is [7369].
empno is [7499].
empno is [7521].
Processing 3 records.
empno is [7566].
empno is [7654].
empno is [7698].
Processing 3 records.
empno is [7782].
empno is [7788].
empno is [7839].
Processing 3 records.
empno is [7844].
empno is [7876].
empno is [7900].
Processing 2 records.
empno is [7902].
empno is [7934].
All done -
(How) Can a SP call the Function which has BULK COLLECT return?
I have a function using BULL COLLECT to put (XML data) many line into a table type record. (I had this as a function because it's gong to call many times).
From one SP program, I will need to call it to get converted XML data info, how should i call it? If it's single line return, I could use
my_result := get_tbl_xml(p_xml);
but when it's table type, even I defined it, it still get error. Here is the program:
Declare (at package spec)
TYPE OrderDtl_Tab IS TABLE OF xxx%ROWTYPE INDEX BY BINARY_INTEGER;
in_OrderDtlTab OrderDtl_Tab;
FUNCTION get_tbl_xml (p_xml IN CLOB ) RETURN OrderDtl_Tab IS
BEGIN
SELECT extractvalue(VALUE(x), '/xxxx/xxxx') AS xxxx BULK COLLECT
INTO in_OrderDtlTab
FROM TABLE(xmlsequence(extract(xmltype(p_xml), '/Order/Lines/*'))) x;
RETURN in_OrderDtlTab;
END;
PROCEDURE SAVE_A (p_xml IN CLOB )
BEGIN
--- how to call get_tbl_xml to get result, so I will be able to insert into DB table
in_OrderDtlTab := get_tbl_xml(p_xml);
END;
--------------------------------------------------------------------------------------------------------------------May be this is better
FUNCTION get_tbl_xml (p_xml IN CLOB ) RETURN OrderDtl_Tab IS
BEGIN
SELECT extractvalue(VALUE(x), '/xxxx/xxxx') AS xxxx BULK COLLECT
INTO in_OrderDtlTab
FROM TABLE(xmlsequence(extract(xmltype(p_xml), '/Order/Lines/*'))) x;
RETURN in_OrderDtlTab;
END;
PROCEDURE SAVE_A (p_xml IN CLOB )
yourrow your_table%rowtype;
BEGIN
--- how to call get_tbl_xml to get result, so I will be able to insert into DB table
in_OrderDtlTab := get_tbl_xml(p_xml);
FORALL myrowtype
IN in_OrderDtlTab .FIRST .. in_OrderDtlTab .LAST
INSERT INTO Your_table
VALUES in_OrderDtlTab(yourrow);
END;
END; -
PL/SQL using BULK COLLECT and MERGE
what i am trying to do is to use bulk collect to create an array of row data, then loop through the array and either insert or update a table, hence, merge:
FORALL i in ID.first .. ID.last SAVE EXCEPTIONS
MERGE INTO table1 t USING (
select ID(i) ID, {other array fields...} from dual) s
ON t.ID = s.ID
WHEN MATCHED THEN UPDATE...
WHEN NOT MATCHED THEN INSERT ...
The problem is that Oracle always do a INSERT. Has anyone had the same problem? Any workaround?
Thanks.in package header:
TYPE ID_TYPE IS TABLE OF table1.ID%TYPE;
in the proc, I declared
ID ID_TYPE;
then a bulk collect:
select * from .. BULK COLLECT INTO ID...
In addition, i truncate the destination table and run the Proc. all records are insert's. then I ran the same proc again, expecting all records to be updated, but insert occured again causing exceptions due to violation of unique keys.
Message was edited by:
zliao01 -
Bulk collection PL/SQL table
Hi all,
10g version 10.2.0.1
What approach can I take to accomplish the following.
I need to build a collection based on the result set of two SQL statements within a loop.
Example:
FUNCTION( get_info )IS
RETURN retrieval_pkg_public_ty
PIPELINED
TYPE ret_tab IS TABLE OF ret_rec;
FOR i IN 1 .. 2
LOOP
SELECT...
BULK COLLECT into ret_tbl
FROM(SELECT...
FROM(SELECT..
quite a large SQL statement...
WHERE
x = parameter_value, --parameter changes on based on i values
y = parameter_value, --parameter changes on based on i values
END LOOP;
FOR i IN ret_tbl.FIRST..ret_tbl.LAST
LOOP
PIPE ROW...
END LOOP;
I can use a global temporary table to hold the results of each loop and them select from gtt, however I would prefer to use a table function.
thanks
Markuser1602736 wrote:
Currently, I have a procedure that is called within a package that returns a SYS_REFCURSOR.
Current code in procedure is
FOR i IN 1..2
LOOP
INSERt INTO gtt
END LOOP;Why not simply populate the GTT using an INSERT INTO gtt SELECT ... FROM source WHERE .. ?
I wanted to avoid creating a gtt to accomplish above.Why? What problems with this GTT approach do you think there are?
The cursor only returns around 50 records. The record has around 20 data fieldsRemember that if you store this as a PL/SQL collection (there's no such thing as PL "+table+"), this collection resides in expensive private process memory (the PGA). If there a 100 sessions using this code, then there will be a 100 copies of this collection.
On the other hand, a GTT does not reside in expensive private memory. And it can scale to a 1000 rows in future, without affecting performance (remember that GTTs can be indexed - collections not). For a collection, you will pay an excessive price in memory for keeping that 1000 rows in the PGA.
GTTs are not a bad thing. Collections are not a bad thing. They are tools for addressing specific problems. Your task is to select the right tool for the job. Caching SQL row data in a PL/SQL collection is almost never the right tool for the job, as it requires private process memory and uses a very simplistic data structure (does not support indexes and so on). -
Exceptional handling using Bulk Collect FORALL
Hi Members,
Following are by DB details
SELECT * FROM v$version;
Oracle9i Enterprise Edition Release 9.2.0.7.0 - 64bit Production
PL/SQL Release 9.2.0.7.0 - Production
CORE 9.2.0.7.0 Production
TNS for HPUX: Version 9.2.0.7.0 - Production
NLSRTL Version 9.2.0.7.0 - ProductionI need to handle exception during Bulk Collect FORALL operation and update the table column with Status_flag as 'E' for given item name and extension id. Below is the code snippet for the same.
declare
k NUMBER;
cursor c_list_price
IS
SELECT /*+ leading(a) */ item_name,
'PUBLISH_TO_PRICE_CATALOG' ATTRIBUTE_NAME,
MAX(DECODE (attribute_name,
'PUBLISH_TO_PRICE_CATALOG',
attribute_value))
ATTRIBUTE_VALUE,
NULL GEOGRAPHY_LEVEL,
NULL GEOGRAPHY_VALUE,
NULL INCLUDE_GEOGRAPHY,
NULL EFFECTIVE_START_DATE,
NULL EFFECTIVE_TO_DATE,
EXTENSION_ID,
NULL PRICING_UNIT,
NULL ATTRIBUTE_FROM,
NULL ATTRIBUTE_TO,
NULL FIXED_BASE_PRICE,
NULL PARENT_ATTRIBUTE,
NULL DURATION_QUANTITY,
NULL ATTRIBUTE2,
NULL ATTRIBUTE3,
NULL ATTRIBUTE4,
NULL ATTRIBUTE5,
NULL ATTRIBUTE6,
NULL ATTRIBUTE7,
NULL ATTRIBUTE8,
NULL ATTRIBUTE9,
NULL ATTRIBUTE10,
NULL ATTRIBUTE11,
NULL ATTRIBUTE12,
NULL ATTRIBUTE13,
NULL ATTRIBUTE14,
NULL ATTRIBUTE15,
--ORG_CODE,
ITEM_CATALOG_CATEGORY ITEM_CATEGORY,
a.INVENTORY_ITEM_ID INVENTORY_ITEM_ID
FROM XXCPD_ITM_SEC_UDA_DETAILS_TB a
WHERE DECODE(attribute_group_name,'LIST_PRICE',DECODE(STATUS_FLAG,'E',1,'P',2,3)
,'XXITM_FORM_PRICING_HS',DECODE(STATUS_FLAG,'E',4,'P',5,6)
,'XXITM_FORM_PRICING_SB',DECODE(STATUS_FLAG,'E',4,'P',5,6)
,'XXITM_ADV_FORM_PRICING_HS',DECODE(STATUS_FLAG,'E',7,'P',8,9)
,'XXITM_ADV_FORM_PRICING_SB',DECODE(STATUS_FLAG,'E',7,'P',8,9)
,'XXITM_ADV_FORM_PRICING_HWSW',DECODE(STATUS_FLAG,'E',10,'P',11,12)
,'XXITM_ADV_FORM_PRICING_SWSUB',DECODE(STATUS_FLAG,'E',10,'P',11,12)
,'XXITM_ROUTE_TO_MARKET',DECODE(STATUS_FLAG,'E',13,'P',14,15)) in (1,2,3)
AND exists(select /*+ no_merge */ '1' from mtl_system_items_b b where a.inventory_item_id=b.inventory_item_id and b.organization_id=1)
GROUP BY item_name,
extension_id,
ITEM_CATALOG_CATEGORY,
INVENTORY_ITEM_ID;
TYPE myarray IS TABLE OF c_list_price%ROWTYPE;
c_lp myarray;
BEGIN
OPEN c_list_price;
LOOP
FETCH c_list_price BULK COLLECT INTO c_lp
LIMIT 50000;
IF c_lp.count = 0 THEN
EXIT;
END IF;
Begin
FORALL i IN c_lp.FIRST..c_lp.LAST SAVE EXCEPTIONS
INSERT /*+append*/ INTO XXCPD_ITEM_PRICING_ATTR_BKP2(
line_id,
ITEM_NAME,
ATTRIBUTE_NAME,
ATTRIBUTE_VALUE,
GEOGRAPHY_LEVEL,
GEOGRAPHY_VALUE,
INCLUDE_GEOGRAPHY,
EFFECTIVE_START_DATE,
EFFECTIVE_TO_DATE,
EXTENSION_ID,
PRICING_UNIT,
ATTRIBUTE_FROM,
ATTRIBUTE_TO,
FIXED_BASE_PRICE,
PARENT_ATTRIBUTE,
DURATION_QUANTITY,
ATTRIBUTE2,
ATTRIBUTE3,
ATTRIBUTE4,
ATTRIBUTE5,
ATTRIBUTE6,
ATTRIBUTE7,
ATTRIBUTE8,
ATTRIBUTE9,
ATTRIBUTE10,
ATTRIBUTE11,
ATTRIBUTE12,
ATTRIBUTE13,
ATTRIBUTE14,
ATTRIBUTE15,
ITEM_CATEGORY,
INVENTORY_ITEM_ID
VALUES
xxcpd.xxcpd_if_prc_line_id_s.NEXTVAL
,c_lp(i).ITEM_NAME
,c_lp(i).ATTRIBUTE_NAME
,c_lp(i).ATTRIBUTE_VALUE
,c_lp(i).GEOGRAPHY_LEVEL
,c_lp(i).GEOGRAPHY_VALUE
,c_lp(i).INCLUDE_GEOGRAPHY
,c_lp(i).EFFECTIVE_START_DATE
,c_lp(i).EFFECTIVE_TO_DATE
,c_lp(i).EXTENSION_ID
,c_lp(i).PRICING_UNIT
,c_lp(i).ATTRIBUTE_FROM
,c_lp(i).ATTRIBUTE_TO
,c_lp(i).FIXED_BASE_PRICE
,c_lp(i).PARENT_ATTRIBUTE
,c_lp(i).DURATION_QUANTITY
,c_lp(i).ATTRIBUTE2
,c_lp(i).ATTRIBUTE3
,c_lp(i).ATTRIBUTE4
,c_lp(i).ATTRIBUTE5
,c_lp(i).ATTRIBUTE6
,c_lp(i).ATTRIBUTE7
,c_lp(i).ATTRIBUTE8
,c_lp(i).ATTRIBUTE9
,c_lp(i).ATTRIBUTE10
,c_lp(i).ATTRIBUTE11
,c_lp(i).ATTRIBUTE12
,c_lp(i).ATTRIBUTE13
,c_lp(i).ATTRIBUTE14
,c_lp(i).ATTRIBUTE15
,c_lp(i).ITEM_CATEGORY
,c_lp(i).INVENTORY_ITEM_ID
EXCEPTION
WHEN OTHERS THEN
FOR j IN 1..SQL%bulk_exceptions.Count
LOOP
UPDATE XXCPD_ITM_SEC_UDA_DETAILS_TB
SET status_flag = 'E',
last_updated_by = 1,
last_update_date = SYSDATE
WHERE item_name = c_lp(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX).item_name
AND extension_id=c_lp(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX).extension_id;
COMMIT;
IF c_list_price%ISOPEN THEN
CLOSE c_list_price;
END IF;
FND_FILE.put_line(FND_FILE.output,'********************Exception Occured*************:-- '||SYSTIMESTAMP);
END LOOP;
END;
END LOOP;
CLOSE c_list_price;
COMMIT;
end;and I am getting following error
ORA-06550: line 156, column 47:
PL/SQL: ORA-00911: invalid character
ORA-06550: line 152, column 21:
PL/SQL: SQL Statement ignoredpointing to following lines in exception block for update clause.
WHERE item_name = c_lp(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX).item_name
AND extension_id=c_lp(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX).extension_id; can some one please help me out with the issue.
Thanks in AdvanceHave re-written the code in the following manner
declare
lv_ITEM_NAME DBMS_SQL.VARCHAR2S;
lv_ITEM_CATEGORY DBMS_SQL.VARCHAR2S;
lv_INVENTORY_ITEM_ID DBMS_SQL.NUMBER_TABLE;
lv_ATTRIBUTE_NAME DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE_VALUE DBMS_SQL.VARCHAR2S;
lv_GEOGRAPHY_LEVEL DBMS_SQL.VARCHAR2S;
lv_GEOGRAPHY_VALUE DBMS_SQL.VARCHAR2S;
lv_INCLUDE_GEOGRAPHY DBMS_SQL.VARCHAR2S;
lv_EFFECTIVE_START_DATE DBMS_SQL.date_table;
lv_EFFECTIVE_TO_DATE DBMS_SQL.date_table;
lv_EXTENSION_ID DBMS_SQL.NUMBER_TABLE;
lv_PRICING_UNIT DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE_FROM DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE_TO DBMS_SQL.VARCHAR2S;
lv_FIXED_BASE_PRICE DBMS_SQL.NUMBER_TABLE;
lv_PARENT_ATTRIBUTE DBMS_SQL.VARCHAR2S;
lv_DURATION_QUANTITY DBMS_SQL.NUMBER_TABLE;
lv_ATTRIBUTE2 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE3 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE4 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE5 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE6 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE7 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE8 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE9 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE10 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE11 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE12 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE13 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE14 DBMS_SQL.VARCHAR2S;
lv_ATTRIBUTE15 DBMS_SQL.VARCHAR2S;
l_item_name XXCPD_ITM_SEC_UDA_DETAILS_TB.item_name%TYPE;
l_extension_id XXCPD_ITM_SEC_UDA_DETAILS_TB.extension_id%TYPE;
cursor c_list_price
IS
SELECT /*+ leading(a) */ item_name,
'PUBLISH_TO_PRICE_CATALOG' ATTRIBUTE_NAME,
MAX(DECODE (attribute_name,
'PUBLISH_TO_PRICE_CATALOG',
attribute_value))
ATTRIBUTE_VALUE,
NULL GEOGRAPHY_LEVEL,
NULL GEOGRAPHY_VALUE,
NULL INCLUDE_GEOGRAPHY,
NULL EFFECTIVE_START_DATE,
NULL EFFECTIVE_TO_DATE,
EXTENSION_ID,
NULL PRICING_UNIT,
NULL ATTRIBUTE_FROM,
NULL ATTRIBUTE_TO,
NULL FIXED_BASE_PRICE,
NULL PARENT_ATTRIBUTE,
NULL DURATION_QUANTITY,
NULL ATTRIBUTE2,
NULL ATTRIBUTE3,
NULL ATTRIBUTE4,
NULL ATTRIBUTE5,
NULL ATTRIBUTE6,
NULL ATTRIBUTE7,
NULL ATTRIBUTE8,
NULL ATTRIBUTE9,
NULL ATTRIBUTE10,
NULL ATTRIBUTE11,
NULL ATTRIBUTE12,
NULL ATTRIBUTE13,
NULL ATTRIBUTE14,
NULL ATTRIBUTE15,
--ORG_CODE,
ITEM_CATALOG_CATEGORY ITEM_CATEGORY,
a.INVENTORY_ITEM_ID INVENTORY_ITEM_ID
FROM XXCPD_ITM_SEC_UDA_DETAILS_TB a
WHERE DECODE(attribute_group_name,'LIST_PRICE',DECODE(STATUS_FLAG,'E',1,'P',2,3)
,'XXITM_FORM_PRICING_HS',DECODE(STATUS_FLAG,'E',4,'P',5,6)
,'XXITM_FORM_PRICING_SB',DECODE(STATUS_FLAG,'E',4,'P',5,6)
,'XXITM_ADV_FORM_PRICING_HS',DECODE(STATUS_FLAG,'E',7,'P',8,9)
,'XXITM_ADV_FORM_PRICING_SB',DECODE(STATUS_FLAG,'E',7,'P',8,9)
,'XXITM_ADV_FORM_PRICING_HWSW',DECODE(STATUS_FLAG,'E',10,'P',11,12)
,'XXITM_ADV_FORM_PRICING_SWSUB',DECODE(STATUS_FLAG,'E',10,'P',11,12)
,'XXITM_ROUTE_TO_MARKET',DECODE(STATUS_FLAG,'E',13,'P',14,15)) in (1,2,3)
AND exists(select /*+ no_merge */ '1' from mtl_system_items_b b where a.inventory_item_id=b.inventory_item_id and b.organization_id=1)
GROUP BY item_name,
extension_id,
ITEM_CATALOG_CATEGORY,
INVENTORY_ITEM_ID;
BEGIN
OPEN c_list_price;
LOOP
lv_ITEM_NAME.delete;
lv_ITEM_CATEGORY.delete;
lv_INVENTORY_ITEM_ID.delete;
lv_ATTRIBUTE_NAME.delete;
lv_ATTRIBUTE_VALUE.delete;
lv_GEOGRAPHY_LEVEL.delete;
lv_GEOGRAPHY_VALUE.delete;
lv_INCLUDE_GEOGRAPHY.delete;
lv_EFFECTIVE_START_DATE.delete;
lv_EFFECTIVE_TO_DATE.delete;
lv_EXTENSION_ID.delete;
lv_PRICING_UNIT.delete;
lv_ATTRIBUTE_FROM.delete;
lv_ATTRIBUTE_TO.delete;
lv_FIXED_BASE_PRICE.delete;
lv_PARENT_ATTRIBUTE.delete;
lv_DURATION_QUANTITY.delete;
lv_ATTRIBUTE2.delete;
lv_ATTRIBUTE3.delete;
lv_ATTRIBUTE4.delete;
lv_ATTRIBUTE5.delete;
lv_ATTRIBUTE6.delete;
lv_ATTRIBUTE7.delete;
lv_ATTRIBUTE8.delete;
lv_ATTRIBUTE9.delete;
lv_ATTRIBUTE10.delete;
lv_ATTRIBUTE11.delete;
lv_ATTRIBUTE12.delete;
lv_ATTRIBUTE13.delete;
lv_ATTRIBUTE14.delete;
lv_ATTRIBUTE15.delete;
FETCH c_list_price BULK COLLECT INTO lv_ITEM_NAME
,lv_ATTRIBUTE_NAME
,lv_ATTRIBUTE_VALUE
,lv_GEOGRAPHY_LEVEL
,lv_GEOGRAPHY_VALUE
,lv_INCLUDE_GEOGRAPHY
,lv_EFFECTIVE_START_DATE
,lv_EFFECTIVE_TO_DATE
,lv_EXTENSION_ID
,lv_PRICING_UNIT
,lv_ATTRIBUTE_FROM
,lv_ATTRIBUTE_TO
,lv_FIXED_BASE_PRICE
,lv_PARENT_ATTRIBUTE
,lv_DURATION_QUANTITY
,lv_ATTRIBUTE2
,lv_ATTRIBUTE3
,lv_ATTRIBUTE4
,lv_ATTRIBUTE5
,lv_ATTRIBUTE6
,lv_ATTRIBUTE7
,lv_ATTRIBUTE8
,lv_ATTRIBUTE9
,lv_ATTRIBUTE10
,lv_ATTRIBUTE11
,lv_ATTRIBUTE12
,lv_ATTRIBUTE13
,lv_ATTRIBUTE14
,lv_ATTRIBUTE15
,lv_ITEM_CATEGORY
,lv_INVENTORY_ITEM_ID
LIMIT 50000;
IF lv_INVENTORY_ITEM_ID.count = 0 THEN
EXIT;
END IF;
Begin
FORALL I IN 1..lv_INVENTORY_ITEM_ID.count SAVE EXCEPTIONS
INSERT /*+append*/ INTO XXCPD_ITEM_PRICING_ATTR_BKP2(
line_id,
ITEM_NAME,
ATTRIBUTE_NAME,
ATTRIBUTE_VALUE,
GEOGRAPHY_LEVEL,
GEOGRAPHY_VALUE,
INCLUDE_GEOGRAPHY,
EFFECTIVE_START_DATE,
EFFECTIVE_TO_DATE,
EXTENSION_ID,
PRICING_UNIT,
ATTRIBUTE_FROM,
ATTRIBUTE_TO,
FIXED_BASE_PRICE,
PARENT_ATTRIBUTE,
DURATION_QUANTITY,
ATTRIBUTE2,
ATTRIBUTE3,
ATTRIBUTE4,
ATTRIBUTE5,
ATTRIBUTE6,
ATTRIBUTE7,
ATTRIBUTE8,
ATTRIBUTE9,
ATTRIBUTE10,
ATTRIBUTE11,
ATTRIBUTE12,
ATTRIBUTE13,
ATTRIBUTE14,
ATTRIBUTE15,
ITEM_CATEGORY,
INVENTORY_ITEM_ID
VALUES
xxcpd.xxcpd_if_prc_line_id_s.NEXTVAL
,lv_ITEM_NAME(i)
,lv_ATTRIBUTE_NAME(i)
,lv_ATTRIBUTE_VALUE(i)
,lv_GEOGRAPHY_LEVEL(i)
,lv_GEOGRAPHY_VALUE(i)
,lv_INCLUDE_GEOGRAPHY(i)
,lv_EFFECTIVE_START_DATE(i)
,lv_EFFECTIVE_TO_DATE(i)
,lv_EXTENSION_ID(i)
,lv_PRICING_UNIT(i)
,lv_ATTRIBUTE_FROM(i)
,lv_ATTRIBUTE_TO(i)
,lv_FIXED_BASE_PRICE(i)
,lv_PARENT_ATTRIBUTE(i)
,lv_DURATION_QUANTITY(i)
,lv_ATTRIBUTE2(i)
,lv_ATTRIBUTE3(i)
,lv_ATTRIBUTE4(i)
,lv_ATTRIBUTE5(i)
,lv_ATTRIBUTE6(i)
,lv_ATTRIBUTE7(i)
,lv_ATTRIBUTE8(i)
,lv_ATTRIBUTE9(i)
,lv_ATTRIBUTE10(i)
,lv_ATTRIBUTE11(i)
,lv_ATTRIBUTE12(i)
,lv_ATTRIBUTE13(i)
,lv_ATTRIBUTE14(i)
,lv_ATTRIBUTE15(i)
,lv_ITEM_CATEGORY(i)
,lv_INVENTORY_ITEM_ID(i)
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
FOR j IN 1..SQL%bulk_exceptions.Count
LOOP
l_item_name:=lv_ITEM_NAME(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX);
l_extension_id:=lv_EXTENSION_ID(SQL%BULK_EXCEPTIONS(j).ERROR_INDEX);
UPDATE XXCPD_ITM_SEC_UDA_DETAILS_TB
SET status_flag = 'E',
last_updated_by = 1,
last_update_date = SYSDATE
WHERE item_name = l_item_name
AND extension_id=l_extension_id;
COMMIT;
FND_FILE.put_line(FND_FILE.output,'********************Exception Occured*************:-- '||SYSTIMESTAMP);
END LOOP;
END;
END LOOP;
CLOSE c_list_price;
COMMIT;
end; -
Passing values dynamically in bulk collect
1. hi for ex 5 account number in a table packages each account number is having of 30 records with the column aol and new(values are in 0 or 1)
i need to copare fro old column and new column values and return if 0 and 1 means return 1 0 and 0 means 0 1and 1 means 1 1and 0 means 0
for all days 30 days. for all account number and ouptut should be as follows
account number value
1 0
2 1
3 1
4 0
and this values should update in another table;
i wrote a sample query for a single account but i need for all accounts.
as given below please help me to solve the issues
DECLARE
CURSOR C1 is select rowid,old_family,new_family,OLD_SPORTS,NEW_SPORTS,OLD_DYNASTY,NEW_DYNASTY from packages where account_no='86240331';
Type C1_type is table of C1%rowtype;
Rec1 c1_type;
New_value1 number;
New_value2 number;
New_value3 number;
Begin
Open C1;
Loop
Fetch C1 Bulk collect into Rec1;
For i in 1..Rec1.count Loop
-------- TO GET FAMILY PACKAGES VALUES-----------------------------------------------------------------------------------------------
If (Rec1(i).old_family= '0' and Rec1(i).new_family ='1' ) or
(Rec1(i).old_family= '1' and Rec1(i).new_family ='1' )
then
new_value1:='1';
Else
new_value1:='0';
End if;
-------- TO GET SPORTS PACKAGES VALUES-----------------------------------------------------------------------------------------------
If (Rec1(i).old_SPORTS= '0' and Rec1(i).new_SPORTS ='1' ) or
(Rec1(i).old_SPORTS= '1' and Rec1(i).new_SPORTS ='1' )
then
new_value2:='1';
Else
new_value2:='0';
End if;
------------TO GET DYNASTY PACKAGES VALUES ------------------------------------------------------------------------------------------
If (Rec1(i).old_DYNASTY= '0' and Rec1(i).new_DYNASTY ='1' ) or
(Rec1(i).old_DYNASTY= '1' and Rec1(i).new_DYNASTY ='1' )
then
new_value3:='1';
Else
new_value3:='0';
End if;
End loop;
--------------------------- update statement------------
Exit when c1%notfound;
End loop;
End;
Edited by: 841719 on Mar 6, 2011 8:01 PM1. hi for ex 5 account number in a table packages each account number is having of 30 records with the column aol and new(values are in 0 or 1)
i need to copare fro old column and new column values and return if 0 and 1 means return 1 0 and 0 means 0 1and 1 means 1 1and 0 means 0
for all days 30 days. for all account number and ouptut should be as follows
account number value
1 0
2 1
3 1
4 0
and this values should update in another table;
i wrote a sample query for a single account but i need for all accounts.
as given below please help me to solve the issues
DECLARE
CURSOR C1 is select rowid,old_family,new_family,OLD_SPORTS,NEW_SPORTS,OLD_DYNASTY,NEW_DYNASTY from packages where account_no='86240331';
Type C1_type is table of C1%rowtype;
Rec1 c1_type;
New_value1 number;
New_value2 number;
New_value3 number;
Begin
Open C1;
Loop
Fetch C1 Bulk collect into Rec1;
For i in 1..Rec1.count Loop
TO GET FAMILY PACKAGES VALUES-----------------------------------------------------------------------------------------------
If (Rec1(i).old_family= '0' and Rec1(i).new_family ='1' ) or
(Rec1(i).old_family= '1' and Rec1(i).new_family ='1' )
then
new_value1:='1';
Else
new_value1:='0';
End if;
TO GET SPORTS PACKAGES VALUES-----------------------------------------------------------------------------------------------
If (Rec1(i).old_SPORTS= '0' and Rec1(i).new_SPORTS ='1' ) or
(Rec1(i).old_SPORTS= '1' and Rec1(i).new_SPORTS ='1' )
then
new_value2:='1';
Else
new_value2:='0';
End if;
------------TO GET DYNASTY PACKAGES VALUES
If (Rec1(i).old_DYNASTY= '0' and Rec1(i).new_DYNASTY ='1' ) or
(Rec1(i).old_DYNASTY= '1' and Rec1(i).new_DYNASTY ='1' )
then
new_value3:='1';
Else
new_value3:='0';
End if;
End loop; update statement------------
Exit when c1%notfound;
End loop;
End; -
Bulk collect seems to retain previous row value when current returns null
Dear all,
I am currently writing package in plsql.
The main logic of the program is as follow .. Program works fine .. but ... when no data is found for current V_1, V_2,V_3 , insertion is done with previous cursor row value of V_1,V_2,V_3, ... which is not good.
I tried to change the last nested cursor with first..last instead of 1..count, but result is the same.
Any idea?
open c_trt;
loop
fetch c_trt bulk collect into bk_trig limit v_limit;
open c_bkeve;
fetch c_bkeve bulk collect into bk_eve limit v_limit;
if bk_eve.count > 0 then
for k in 1..bk_eve.count loop;
case
when a =1 then
open c_bkieve(bk_eve(k).age,bk_eve(k).ope, bk_eve(k).eve);
fetch c_bkieve bulk collect into bk_ieve limit v_limit;
if bk_ieve.count > 0 then
for j in 1..bk_ieve.count loop
fetch c_bkieve bulk collect into bk_ieve limit v_limit;
if bk_ieve.count > 0 then
for j in 1..bk_ieve.count loop
case bk_ieve(j).a
when 'ABC' then
V_1 := nvl(trim(bk_ieve(j).b),null);
when 'XYZ' then
V_2 := nvl(trim(substr(bk_ieve(j).b,1,4)),null);
V_3 := nvl(trim(substr(bk_ieve(j).b,6,22)),null);
else
null;
end case;
end loop;
else
V_1 := null;
V_2 := null;
V_3 := null;
end if;
close c_bkieve;
insert into xxx values(V_1,V_2,V_3);
etc, etc
Thanks for your help
JeromeSomething like this
select a.dco
, a.agsa
, a.agem
, a.agde
, a.ope
, a.eve
, a.tpr
, a.nat
, a.age
, a.dev
, a.ncp
, a.suf
, a.sen
, a.dva
, a.mon
, a.lib
, c.cli
from bmvtg_mi a
join bcom c
on a.age = c.age
and a.dev = c.dev
and a.ncp = c.ncp
and a.suf = c.suf
join (
select x.*
, y.cur_char
from bkeve_mi x
left join wb_currency y
on x.csp4 = y.cur_num
) b
on b.age = decode(v_var1, 'age', a.age, 'agem', a.agem, 'agsa', a.agsa, 'agde', a.agde, a.age)
where exists
select *
from wb_client sc
where c.cli = sc.customer_number
and ready = 1
and exists
select *
from wb_pdt sp
where c.cpro = sp.c_pro
Maybe you are looking for
-
Office Home and Student 2010 Install problems with a Key Code Err..
I had to install a new hard drive, lost everything..So I upgraded to Windows 7 Professional .. I own a the 2010 Home and Student CD bought at the Microsoft store...Doesn't come with Outlook... So I ordered the Home and Business 2010 disc with Service
-
Photos for iOS: How can i sort all of my albums automatically in alphabetical order
Hey there, first off, why isn't there a a community for the new Photos app? Anyway, here is my problem: How can i sort my albums on the new Photos app on iOS? I think it's not possible at the moment. I am using the iCloud Photo library and uploadet a
-
When I click the + sign to open a new blank tab, I don't see any of my favorite / pinned websites. I can only see this when I start a new browser window, and only for the "landing page". Once I go to any other page, I can not get my new tab page with
-
How to fix Adobe App Manager error code -60 Download appears corrupt but only for Photoshop CS6 app
How to fix Adobe App Manager error code -60 Download appears corrupt but only for Photoshop CS6 Creative Suite Cloud App. Many attempts were made to install Photoshop CS6 with Adobe Application Manager without success. Every other Creative Suite Appl
-
Hi, Just recently I bought a Zen Touch. I've always charged after the "low battery" sign is displayed, played songs at 92 Kbps, and rarely used equilizer settings. However, I'm still beginning to notice severe shortening of battery life. Can anyone t