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 PM
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;
Similar Messages
-
Pass values dynamically to the WHERE clause in SFAPI
Hi there
We have a requirement to pass values dynamically (in the run-time of the interface) to the WHERE condition to our SFAPI query.
Eg -
SELECT person, personal_information, address_information, phone_information, email_information, employment_information, job_information, compensation_information, paycompensation_recurring, paycompensation_non_recurring, job_relation, accompanying_dependent, global_assignment_information, direct_deposit, national_id_card, person_relation
FROM CompoundEmployee
WHERE last_modified_on >= to_date('LAST_RUN_DATE') AND
last_modified_on <= to_date('CURRENT_RUN_TIME')
LAST_RUN_DATE is stored in a custom entity for which we execute another OData query. The custom entity is updated with the CURRENT_RUN_TIME once the interface has been executed successfully. So the next time the interface is run it picks up the LAST_RUN_DATE from the custom OData entity.
SAP PO has the functionality to run a dynamic query for OData adapters. Refer to Note 2051137 - PI Successfactors adapter : Dynamic odata query and single synchronous sfapi query
Eg - select fields from position (this is what you state in OData query path in the comms channel; this is static); and you have an advanced tab in comms channel where you mention dynamicquery and set it to true (this points to a XSD which has the keyword TOP, SKIP & FILTER in it).
This gets the filter values passed from the BPM from another query (from a OData cust_table).
So the whole query is - select fields from position filter field a = x field b = y etc. Field a field b are fields in position that are you passing values x and y in run time of the interface.
SAP PO also has the advanced tab feature for SFAPI for dynamic query.
Question is -
how to use it?
has anyone implemented this before?
What does XSD will look like?
How do we pass values to the fields to the Where clause for SFAPI.
Any ideas are welcome!
Regards
Arijit DasAfter you have added a new where clause on the detail VO, try re-executing VO's query by DetailVO.executeQuery()
If it doesn't work try re-executing the MasterVO's query after you have added the where clause on the detail -
Passing values dynamically Froman 'INLINE Query' to a 'SUB QUERY'
If I am using an line query which uses a SELF JOIN subquery
how can I pass the values from the Inline Query to Subquery ?
Is this possible?
SQL...Code
and Inline Queries..
(select count(*) 'PrimaryISIN'
from instrument ins,
instrument_xref insx
where ins.id_inst = insx.id_inst
and insx.flg_active = 'Y'
and ins.id_source ='MF'
and ins.flg_primary_listing = 'Y'
and ins.flg_active = 'Y'
and insx.id_inst_xref = ( select DISTINCT a.id_inst_xref
from instrument_xref a,
instrument_xref b
where b.id_inst_xref ='B0DV8Y9'
and b.id_inst = a.id_inst
and b.id_inst_xref_type in ('SE','IS')
and a.id_inst_xref = 'GB00B03MLX29'
)PISIN2
I am hardcoding the id_inst_xref is the SELF JOIN? Can these be passed dynamically from
the INLINE Query which is invoking the SUB QUERY?Hi, The hardcoded values entered in the SELF JOIN run fine.
Now,I need to pass values dynamically from the INLINE query.
How do I do that?
Thanks -
Issue in using Cursor+Dynamic SQL+ Bulk collect +FORALL
Hi,
I have a dynamic query which I need to use as a cursor to fetch records that inturn need to be inserted into a staging table.
The issue I am facing is I am not sure how to declare the variable to fetch the records into. Since I am using a dynamic cursor how do I declare it?
My code looks something like this -
TYPE c_details_tbl_type IS REF CURSOR;
c_details c_details_tbl_type;
TYPE c_det_tbl_type IS TABLE OF c_details%ROWTYPE INDEX BY PLS_INTEGER;
c_det_tbl c_det_tbl_type; -- ???
BEGIN
v_string1 := 'SELECT....'
v_string2 := ' UNION ALL SELECT....'
v_string3 := 'AND ....'
v_string := v_string1||v_string2||v_string3;
OPEN c_details FOR v_string;
LOOP
FETCH c_details BULK COLLECT
INTO c_det_tbl LIMIT 1000;
IF (c_det_tbl.COUNT > 0) THEN
DELETE FROM STG;
FORALL i IN 1..c_det_tbl.COUNT
INSERT INTO STG
VALUES (c_det_tbl(i));
END IF;
EXIT WHEN c_details%NOTFOUND;
END LOOP;
CLOSE c_details;
END
ThanksWhy the bulk collect? All that this does is slow down the read process (SELECT) and write process (INSERT).
Data selected needs (as a collection) to be pushed into the PGA memory of the PL/SQL engine. And then that very same data needs to be pushed again by the PL/SQL engine back to the database to be inserted. Why?
It is a lot faster, needs a lot less resources, with fewer moving parts, to simply instruct the SQL engine to do both these steps using a single INSERT..SELECT statement. And this can support parallel DML too for scalability when data volumes get large.
It is also pretty easy to make a single SQL statement like this dynamic and even support bind variables.
Simplicity is the ultimate form of elegance. Pushing data needlessly around is not simple and thus not a very elegant way to address the problem. -
Hello Experts,
I am trying to test usage of f4 help function module.
We want to dynamically pass values from remote machines into the given input parameters of a Given Search help and receive the output into a table (no dialogs required .. so no pop ups )
I wrote a test program to just test if we can really do that at runtime ?
This program pops up the window of search help First I want to surpress that window and Second I have no clue
( How to pass the input parameters as value eg. 20 to a given field as we pass manually )
Can some one suggest something here ?
REPORT ZTEST_F4_TEST.
data lt_return TYPE TABLE OF DDSHRETVAL.
data ls_return TYPE DDSHRETVAL.
data lt_return_ddic TYPE TABLE OF zDDSHRETVAL.
data ls_return_ddic TYPE zDDSHRETVAL.
PARAMETERS ptable type tabname.
PARAMETERS pfield type fieldname.
PARAMETERS pshelp type SHLPNAMe.
CALL FUNCTION 'F4IF_FIELD_VALUE_REQUEST'
EXPORTING
tabname = ptable
fieldname = pfield
SEARCHHELP = pshelp
* SHLPPARAM = ' '
* DYNPPROG = ' '
* DYNPNR = ' '
* DYNPROFIELD = ' '
* STEPL = 0
* VALUE = ' '
MULTIPLE_CHOICE = 'X'
DISPLAY = 'F'
SUPPRESS_RECORDLIST = 'X'
* CALLBACK_PROGRAM = ' '
* CALLBACK_FORM = ' '
* SELECTION_SCREEN = ' '
* IMPORTING
* USER_RESET =
TABLES
RETURN_TAB = lt_return
* EXCEPTIONS
* FIELD_NOT_FOUND = 1
* NO_HELP_FOR_FIELD = 2
* INCONSISTENT_HELP = 3
* NO_VALUES_FOUND = 4
* OTHERS = 5
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
data lv_count type i.
delete lt_return where fieldname <> pfield.
sort lt_return by fieldval.
delete ADJACENT DUPLICATES FROM lt_return COMPARING fieldval.Hello Sim,
We will be exposing the Input parameters and Output lists of the SAP Search helps (simple search helps only) as input output of a Webservice.
So I need to understand how can we exploit the SAP Search Helps ?
What function modules can take these inputs as structures and can provide the output in form of a table ?
Regards,
Ravi -
Passing Value Dynamically in a string
hi All ,
i have a requirement in which i have to pass value of a parameter dynamically to a string
e.g.
param = 10.
data : txt type string .
txt = 'value of param'.
should give a result
value of 10.
here i need to have the value 10 of param in the string ,
how can this be done dynamically
thanks in advance
AbhishekHi Abhishek,
if you know where is the word 'param' in the sentence, you could play with the field symbols.
Good luck
Frédéric -
I need to pass values dynamically into schedular
I need to pass the values into the schedular dynamically like 2 hours ,4 hours ,i minute and soon ...
Hi,
If you want the job to be created automatically, you can create a master job which checks every few minutes and creates another job on the fly if needed.
I don't understand the part about "sending the messages to the admin" but the body of the job can certainly send e-mail or AQ messages.
Hope this helps,
Ravi. -
Too many values when trying insert records by bulk collect
Hi
Can anyone advice on the bulk collect error please?
Following is my code where I am getting too many values error...
TYPE p_empid_type IS TABLE OF emp%ROWTYPE;
v_empid p_empid_type;
BEGIN
SELECT DISTINCT emp_id , 'ABC'
BULK COLLECT INTO v_empid
FROM emp
WHERE empid IN (SELECT ord_id
FROM table_x
WHERE column_x = 'ABC');
FORALL i IN v_empid.FIRST .. v_empid.LAST
INSERT INTO my_table
VALUES v_empid(i);
COMMIT;
PL/SQL: ORA-00913: too many values in line - BULK COLLECT INTO v_empidHello, since you're SELECTing a constant string, why not:
TYPE p_empid_type IS TABLE OF INTEGER;
v_empid p_empid_type;
BEGIN
SELECT DISTINCT emp_id
BULK COLLECT INTO v_empid
FROM emp
WHERE empid IN (SELECT ord_id
FROM table_x
WHERE column_x = 'ABC');
FORALL i IN v_empid.FIRST .. v_empid.LAST
INSERT INTO my_table
VALUES v_empid(i), 'ABC';
Edit Untested: may not work
This would be the best BULK COLLECT of all:
INSERT /*+ APPEND */ INTO my_table
SELECT DISTINCT emp_id , 'ABC'
FROM emp
WHERE empid IN (SELECT ord_id
FROM table_x
WHERE column_x = 'ABC');
COMMIT; -
Bulk collect statement is not working
Hi
I am executing the following scripts
declare
Type r_info is record
name varchar2(1000),
value varchar2(1000),
TL varchar2(100),
id varchar2(100)
Type t_info is table of r_info;
l_info t_info;
begin
SELECT name, value,TL,id
bulk collect into l_info
FROM table1;
end;
it's giving me the following error. Could you please guide me?
PL/SQL: SQL Statement ignored
PL/SQL: ORA-00947: not enough valuesBut now look closely at this:
SQL>select * from v$version;
BANNER
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
PL/SQL Release 9.2.0.8.0 - Production
CORE 9.2.0.8.0 Production
TNS for IBM/AIX RISC System/6000: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production
SQL>set serveroutput on
SQL>declare
2 type r_info is record(
3 name varchar2(1000),
4 value varchar2(1000),
5 tl varchar2(100),
6 id varchar2(100)
7 );
8
9 type t_info is table of r_info;
10
11 l_info t_info;
12 begin
13 select name,
14 value,
15 tl,
16 id
17 bulk collect into l_info
18 from (select 'a' as name, 'a' as value, 'a' as tl, 'a' as id
19 from dual);
20 dbms_output.put_line(l_info(1).name);
21 end;
22 /
a
PL/SQL procedure successfully completed.So, at least in 9.2.0.8.0, Oracle creates a record from these four values automatically and inserts it into the collection.
Wouldn't it be interesting to see what "DESC table1" tells? Maybe value has a composite type...
Urs -
Passing values for a prepared statement encounters problem
I have a query which runs fine when executed from sqlplus
SELECT SYSDATE + (INTERVAL '10' MINUTE) FROM dual;
The same query when run using a java statement also works well.
when I use a Prepared statement like
String sql = SELECT SYSDATE + (INTERVAL ? MINUTE) FROM dual;
PreparedStatement ps = this.getPreparedStatement(sql.toString());
ps.setString(1, "10");
and execute I get the following exception
ORA-00920: invalid relational operator
I tried another way which also gives me a similar exception
String timeout = "10";
SELECT SYSDATE + (INTERVAL" + timeout + "MINUTE) FROM dual;
Can anybody tell me why the problem happens. Is anything wrong in passing values dynamically for an 'interval' function in oracle?asokan_srini wrote:
Yes friends
Thanks for the reply. It worked out this way as u said
sql.append("SELECT SYSDATE + (INTERVAL ");
sql.append("'" + Integer.parseInt(timeout) + "' MINUTE) FROM dual");
Mr.masijade said.
First of all, there is no reason to do this command, really, but okay.
There may be scenarios like this to use the command
select * from mytable where (systimestamp - lastUpdateTimestamp) > Interval '10' Minute
Is there any other better way to get all records updated before a certain timestamp?Use Timestamp to create a timestamp and PreparedStatement's setTimestamp(), maybe? -
BULKING and FORALL statement does not pass values to non DML statements.
Hi
I've got million rows that i need to manapulate and insert into various procedures depending on the bussiness rule to be applied, but my dilemma is that the BULIKNG with a combination of a FORALL statement its not compatible(only considers straightforward DML calls) or the the FORALL does not like other SQL statements or calls as it prefers only DML's.
Below is code fragment that is problamatic as the compiler keeps sending me this error: PLS-00201: identifier 'INDX' must be declared
I want to manupulate data on the implicity cursor and call a procedure to do other stuff which don't use INSERT/DELETE or UPDATE statements.
Declare
TYPE tab_person_id is of table of number(15);
l_person_id tab_person_id;
BEGIN
SELECT person_id
BULK COLLECT INTO l_person_id
FROM person_details; /*-Million records-*/
FORALL indx IN l_tdtl.FIRST..l_tdtl.LAST
pj_pkg.ins_intf
(p_user => p_user,
p_typ_cd => '00',
p_person_id => l_person(indx)
Commit;
END;
How do I pass this value 'l_person(indx)' on the package procudure ?
Thanks
Amos@prabodh:
SQL> declare
2 TYPE tab_person_id is of table of number(15) index by pls_integer;
3 begin
4 null;
5 end;
6 /
TYPE tab_person_id is of table of number(15) index by pls_integer;
ERROR at line 2:
ORA-06550: line 2, column 23:
PLS-00103: Encountered the symbol "OF" when expecting one of the following:
( array limited new private range record VARRAY_ char_base
number_base decimal date_base clob_base blob_base bfile_base
table ref object fixed varying opaque sparse
The symbol "OF" was ignored.Check What you are posting.
@ qwestion: What is your Database Version? It is a implementation restriction. -
Bulk Collect with FORALL not working - Not enough values error
Hi,
I am trying to copy data from one table to another which are having different number of columns. I am doing the following. But it threw not enough values error.
Table A has more than 10 millions of records. So I am using bulk collect instead of using insert into select from.
TABLE A (has more columns - like 25)
c1 Number
c2 number
c3 varchar2
c4 varchar2
c25 varchar2
TABLE B (has less columns - like 7)
c1 Number
c2 number
c3 varchar2
c4 varchar2
c5 number
c7 date
c10 varchar2
declare
TYPE c IS REF CURSOR;
v_c c;
v_Sql VARCHAR2(2000);
TYPE array is table of B%ROWTYPE;
l_data array;
begin
v_Sql := 'SELECT c1, c2, c3, c4, c5, c7, c10 FROM A ORDER BY c1';
OPEN v_c FOR v_Sql;
LOOP
FETCH v_c BULK COLLECT INTO ldata LIMIT 100000;
FORALL i in 1 .. ldata.count
INSERT
INTO B
VALUES ldata(i);
END LOOP;
COMMIT;
exception
WHEN OTHERS THEN
ROLLBACK;
dbms_output.put_line('Exception Occurred' || SQLERRM);
END;
When I execute this, I am getting
PL/SQL: ORA-00947: not enough values
Any suggestions please. Thanks in advance.Table A has more than 10 millions of records. So I am using bulk collect instead of using insert into select from.That doesn't make sense to me. An INSERT ... SELECT is going to be more efficient, more maintainable, easier to write, and easier to understand.
INSERT INTO b( c1, c2, c3, c4, c5, c7, c10 )
SELECT c1, c2, c3, c4, c5, c7, c10
FROM a;is going to be faster, use fewer resources, be far less error-prone, and have a far more obvious purpose when some maintenance programmer comes along than any PL/SQL block that does the same thing.
If you insist on using PL/SQL, what version of Oracle are you using? You should be able to do something like
DECLARE
TYPE b_tbl IS TABLE OF b%rowtype;
l_array b_tbl;
CURSOR a_cursor
IS SELECT c1, c2, c3, c4, c5, c7, c10 FROM A;
BEGIN
OPEN a_cursor;
LOOP
FETCH a_cursor
BULK COLLECT INTO l_array
LIMIT 10000;
EXIT WHEN l_array.COUNT = 0;
FORALL i IN l_array.FIRST .. l_array.LAST
INSERT INTO b
VALUES l_array(i);
END LOOP;
COMMIT;
END;That at least eliminates the infinite loop and the unnecessary dynamic SQL. If you're using older versions of Oracle (it's always helpful to post that information up front), the code may need to be a bit more complex.
Justin
Edited by: Justin Cave on Jan 19, 2011 5:46 PM -
BULK COLLECT and FORALL with dynamic INSERT.
Hello,
I want to apply BULK COLLECT and FORALL feature for a insert statement in my procedure for performance improvements as it has to insert a huge amount of data.
But the problem is that the insert statement gets generated dynamically and even the table name is found at the run-time ... so i am not able to apply the performance tuning concepts.
See below the code
PROCEDURE STP_MES_INSERT_GLOBAL_TO_MAIN
(P_IN_SRC_TABLE_NAME VARCHAR2 ,
P_IN_TRG_TABLE_NAME VARCHAR2 ,
P_IN_ED_TRIG_ALARM_ID NUMBER ,
P_IN_ED_CATG_ID NUMBER ,
P_IN_IS_PIECEID_ALARM IN CHAR,
P_IN_IS_LAST_RECORD IN CHAR
IS
V_START_DATA_ID NUMBER;
V_STOP_DATA_ID NUMBER;
V_FROM_DATA_ID NUMBER;
V_TO_DATA_ID NUMBER;
V_MAX_REC_IN_LOOP NUMBER := 30000;
V_QRY1 VARCHAR2(32767);
BEGIN
EXECUTE IMMEDIATE 'SELECT MIN(ED_DATA_ID), MAX(ED_DATA_ID) FROM '|| P_IN_SRC_TABLE_NAME INTO V_START_DATA_ID , V_STOP_DATA_ID;
--DBMS_OUTPUT.PUT_LINE('ORIGINAL START ID := '||V_START_DATA_ID ||' ORIGINAL STOP ID := ' || V_STOP_DATA_ID);
V_FROM_DATA_ID := V_START_DATA_ID ;
IF (V_STOP_DATA_ID - V_START_DATA_ID ) > V_MAX_REC_IN_LOOP THEN
V_TO_DATA_ID := V_START_DATA_ID + V_MAX_REC_IN_LOOP;
ELSE
V_TO_DATA_ID := V_STOP_DATA_ID;
END IF;
LOOP
BEGIN
LOOP
V_QRY1 := ' INSERT INTO '||P_IN_TRG_TABLE_NAME||
' SELECT * FROM '||P_IN_SRC_TABLE_NAME ||
' WHERE ED_DATA_ID BETWEEN ' || V_FROM_DATA_ID ||' AND ' || V_TO_DATA_ID;
EXECUTE IMMEDIATE V_QRY1;
commit;
V_FROM_DATA_ID := V_TO_DATA_ID + 1;
IF ( V_STOP_DATA_ID - V_TO_DATA_ID > V_MAX_REC_IN_LOOP ) THEN
V_TO_DATA_ID := V_TO_DATA_ID + V_MAX_REC_IN_LOOP;
ELSE
V_TO_DATA_ID := V_TO_DATA_ID + (V_STOP_DATA_ID - V_TO_DATA_ID);
END IF;
EXCEPTION
WHEN OTHERS THEN.............
....................so on Now you can observer here that P_IN_SRC_TABLE_NAME is the source table name which we get as a parameter at run-time. I have used 2 table in the insert statement P_IN_TRG_TABLE_NAME (in which i have to insert data) and P_IN_SRC_TABLE_NAME(from where i have to insert data)
V_QRY1 := ' INSERT INTO '||P_IN_TRG_TABLE_NAME||
' SELECT * FROM '||P_IN_SRC_TABLE_NAME ||
' WHERE ED_DATA_ID BETWEEN ' || V_FROM_DATA_ID ||' AND ' || V_TO_DATA_ID;
EXECUTE IMMEDIATE V_QRY1;now when i appy the bulk collect and forall feature i am facing the out of scope problem....see the code below ...
BEGIN
EXECUTE IMMEDIATE 'SELECT MIN(ED_DATA_ID), MAX(ED_DATA_ID) FROM '|| P_IN_SRC_TABLE_NAME INTO V_START_DATA_ID , V_STOP_DATA_ID;
--DBMS_OUTPUT.PUT_LINE('ORIGINAL START ID := '||V_START_DATA_ID ||' ORIGINAL STOP ID := ' || V_STOP_DATA_ID);
V_FROM_DATA_ID := V_START_DATA_ID ;
IF (V_STOP_DATA_ID - V_START_DATA_ID ) > V_MAX_REC_IN_LOOP THEN
V_TO_DATA_ID := V_START_DATA_ID + V_MAX_REC_IN_LOOP;
ELSE
V_TO_DATA_ID := V_STOP_DATA_ID;
END IF;
LOOP
DECLARE
TYPE TRG_TABLE_TYPE IS TABLE OF P_IN_SRC_TABLE_NAME%ROWTYPE;
V_TRG_TABLE_TYPE TRG_TABLE_TYPE;
CURSOR TRG_TAB_CUR IS
SELECT * FROM P_IN_SRC_TABLE_NAME
WHERE ED_DATA_ID BETWEEN V_FROM_DATA_ID AND V_TO_DATA_ID;
V_QRY1 varchar2(32767);
BEGIN
OPEN TRG_TAB_CUR;
LOOP
FETCH TRG_TAB_CUR BULK COLLECT INTO V_TRG_TABLE_TYPE LIMIT 30000;
FORALL I IN 1..V_TRG_TABLE_TYPE.COUNT
V_QRY1 := ' INSERT INTO '||P_IN_TRG_TABLE_NAME||' VALUES V_TRG_TABLE_TYPE(I);'
EXECUTE IMMEDIATE V_QRY1;
EXIT WHEN TRG_TAB_CUR%NOTFOUND;
END LOOP;
CLOSE TRG_TAB_CUR;
V_FROM_DATA_ID := V_TO_DATA_ID + 1;
IF ( V_STOP_DATA_ID - V_TO_DATA_ID > V_MAX_REC_IN_LOOP ) THEN
V_TO_DATA_ID := V_TO_DATA_ID + V_MAX_REC_IN_LOOP;
ELSE
V_TO_DATA_ID := V_TO_DATA_ID + (V_STOP_DATA_ID - V_TO_DATA_ID);
END IF;
EXCEPTION
WHEN OTHERS THEN.........so on
But the above code is not helping me , what i am doing wrong ??? how can i tune this dynamically generated statement to use bulk collect for better performace ......
Thanks in Advance !!!!Hello,
a table name cannot be bind as a parameter in SQL, this wont't compile:
EXECUTE IMMEDIATE ' INSERT INTO :1 VALUES ......
USING P_IN_TRG_TABLE_NAME ...but this should work:
EXECUTE IMMEDIATE ' INSERT INTO ' || P_IN_TRG_TABLE_NAME || ' VALUES ......You cannot declare a type that is based on a table which name is in a variable.
PL/SQL is stronly typed language, a type must be known at compile time, a code like this is not allowed:
PROCEDURE xx( src_table_name varchar2 )
DECLARE
TYPE tab IS TABLE OF src_table_name%ROWTYPE;
...This can be done by creating one big dynamic SQL - see example below (tested on Oracle 10 XE - this is a slightly simplified version of your procedure):
CREATE OR REPLACE
PROCEDURE stp1(
p_in_src_table_name VARCHAR2 ,
p_in_trg_table_name VARCHAR2 ,
v_from_data_id NUMBER := 100,
v_to_data_id NUMBER := 100000
IS
BEGIN
EXECUTE IMMEDIATE q'{
DECLARE
TYPE trg_table_type IS TABLE OF }' || p_in_src_table_name || q'{%ROWTYPE;
V_TRG_TABLE_TYPE TRG_TABLE_TYPE;
CURSOR TRG_TAB_CUR IS
SELECT * FROM }' || p_in_src_table_name ||
q'{ WHERE ED_DATA_ID BETWEEN :V_FROM_DATA_ID AND :V_TO_DATA_ID;
BEGIN
OPEN TRG_TAB_CUR;
LOOP
FETCH TRG_TAB_CUR BULK COLLECT INTO V_TRG_TABLE_TYPE LIMIT 30000;
FORALL I IN 1 .. V_TRG_TABLE_TYPE.COUNT
INSERT INTO }' || p_in_trg_table_name || q'{ VALUES V_TRG_TABLE_TYPE( I );
EXIT WHEN TRG_TAB_CUR%NOTFOUND;
END LOOP;
CLOSE TRG_TAB_CUR;
END; }'
USING v_from_data_id, v_to_data_id;
COMMIT;
END;But this probably won't give any performace improvements. Bulk collect and forall can give performance improvements when there is a DML operation inside a loop,
and this one single DML operates on only one record or relatively small number of records, and this DML is repeated many many times in the loop.
I guess that your code is opposite to this - it contains insert statement that operates on many records (one single insert ~ 30000 records),
and you are trying to replace it with bulk collect/forall - INSERT INTO ... SELECT FROM will almost alwayst be faster than bulk collect/forall.
Look at simple test - below is a procedure that uses INSERT ... SELECT :
CREATE OR REPLACE
PROCEDURE stp(
p_in_src_table_name VARCHAR2 ,
p_in_trg_table_name VARCHAR2 ,
v_from_data_id NUMBER := 100,
v_to_data_id NUMBER := 100000
IS
V_QRY1 VARCHAR2(32767);
BEGIN
V_QRY1 := ' INSERT INTO '|| P_IN_TRG_TABLE_NAME ||
' SELECT * FROM '|| P_IN_SRC_TABLE_NAME ||
' WHERE ed_data_id BETWEEN :f AND :t ';
EXECUTE IMMEDIATE V_QRY1
USING V_FROM_DATA_ID, V_TO_DATA_ID;
COMMIT;
END;
/and we can compare both procedures:
SQL> CREATE TABLE test333
2 AS SELECT level ed_data_id ,
3 'XXX ' || LEVEL x,
4 'YYY ' || 2 * LEVEL y
5 FROM dual
6 CONNECT BY LEVEL <= 1000000;
Table created.
SQL> CREATE TABLE test333_dst AS
2 SELECT * FROM test333 WHERE 1 = 0;
Table created.
SQL> set timing on
SQL> ed
Wrote file afiedt.buf
1 BEGIN
2 FOR i IN 1 .. 100 LOOP
3 stp1( 'test333', 'test333_dst', 1000, 31000 );
4 END LOOP;
5* END;
SQL> /
PL/SQL procedure successfully completed.
Elapsed: 00:00:22.12
SQL> ed
Wrote file afiedt.buf
1 BEGIN
2 FOR i IN 1 .. 100 LOOP
3 stp( 'test333', 'test333_dst', 1000, 31000 );
4 END LOOP;
5* END;
SQL> /
PL/SQL procedure successfully completed.
Elapsed: 00:00:14.86without bulk collect ~ 15 sec.
bulk collect version ~ 22 sec. .... 7 sec longer / 15 sec. = about 45% performance decrease. -
Any way to use cursor values inside other cursor by bulk collect?
hi,
Is there any way to use cursor get_tables value insdide loop get column if i am using bulk collect in both cursors?
I tried a lot but i am nt able to do it.kindly help...
create or replace procedure MULTIPLE_CURSORS_PROC is
v_owner varchar2(40);
v_table_name varchar2(40);
v_column_name varchar2(100);
cursor get_tables is
select distinct tbl.owner, tbl.table_name
from all_tables tbl
where tbl.owner = 'SYSTEM';
cursor get_columns is
select distinct col.column_name
from all_tab_columns col
where col.owner = v_owner
and col.table_name = v_table_name;
begin
open get_tables;
loop
fetch get_tables into v_owner, v_table_name;
open get_columns;
loop
fetch get_columns into v_column_name;
end loop;
close get_columns;
end loop;
close get_tables;
end ;hi there
Refer this
CREATE OR REPLACE PROCEDURE MULTIPLE_CURSORS_PROC
IS
TYPE scol IS VARRAY (10000) OF VARCHAR2 (32767);
v_table_name scol;
v_column_name scol;
TYPE curtyp IS REF CURSOR;
get_columns curtyp;
CURSOR get_tables
IS
SELECT DISTINCT tbl.table_name
FROM all_tables tbl
WHERE tbl.owner = 'SYSTEM';
BEGIN
OPEN get_tables;
LOOP
FETCH get_tables BULK COLLECT INTO v_table_name;
FOR indx IN v_table_name.FIRST .. v_table_name.LAST
LOOP
SELECT DISTINCT col.column_name
BULK COLLECT
INTO v_column_name
FROM all_tab_columns col
WHERE col.table_name = v_table_name (indx);
FOR ind IN v_column_name.FIRST .. v_column_name.LAST
LOOP
DBMS_OUTPUT.put_line (v_column_name (ind));
END LOOP;
END LOOP;
EXIT WHEN get_tables%NOTFOUND;
END LOOP;
CLOSE get_tables;
END MULTIPLE_CURSORS_PROC;regards
Hitesh -
In Drop Down by Index how can i pass default value Dynamically
Hi Friends,
In Drop Down by Index how can i pass default value Dynamically.Please help me.
Thanks in advance.
Regards,
Kumar.hi,
if you want the value to be defaulted only the first time you execute the program then write the code which suman has mentioned in the views method
wddoinit.
Regards
Sajid
Maybe you are looking for
-
How do i convert a datetime from java interface and submit into SQL database?
-
Mapping runs through Deployment Manager but hangs in Process Flow
Hi, I have a Mapping bound in a simple Process Flow. The mapping deploys through Deployment Manager and runs. It currently processes no rows and takes a couple of seconds to do that. It completes with a Success message. However, when I wrap it into a
-
GroupWise 8.0.3 patch on NetWare server
I read that there were some problems with the GroupWise 8.0.3 patch on a NetWare box. Have these been resolved with the current version?
-
Assistance with retrieving File and Version on a file with "custom file properties"
Morning, I am attempting to get the file version and date info from a file on multiple workstations on our network. I already know the file location, name and even which workstations the file is on. What I cannot get the script to do is query them an
-
and burn it onto a disc and install it on my iBook. I am currently running Tiger (10.4.8) and need to upgrade to Leopard. I have a 4.7G DVD and a Double Layer 8.5G DVD. (not sure what the double layer is for, but I do have one.) I do not know how lar