PL/SQL block to populate a table
Hello Gurus,
Need help to write a pl/sql block as per below:
1. Write a PL/SQL block which will populate the RESULTS table as described below. Consider performance implications (specifically where would you commit the queries) as we are dealing with millions of records.
The PL/SQL will:
- insert into the RESULTS table each customer id, and the number of unique products purchased by that customer.
- update the recently_purchased column of the customer table to 'Y' (yes if they have purchased a product in the last 12 months) or 'N' (if they have not purchased a product in the last 12 months).
Listed below are the tables & definitions:
table: CUSTOMER
columns:
customer_id NUMBER,
customer_name VARCHAR2(100),
recently_purchased VARCHAR2(1) -- 'Y' or 'N'
table: CUST_PRODUCTS
columns:
product_id NUMBER,
customer_id NUMBER,
date_purchased DATE
table: RESULTS
columns: customer_id NUMBER, product_count NUMBER
Thanks a lot..
Hi Guys,
I've tried this to my best but I feel like something's definately wrong with my update statement.
Please help..
--create customer table
create table customer (
customer_id number(6),
customer_name varchar2(100),
recently_purchased varchar2(1));
-- describe to see if it is created as required
desc customer
--populate customer table with random values
Begin
For i in 1..20
Loop
Insert into customer(customer_id,customer_name,recently_purchased)
values(i, dbms_random.string('U',5),'N');
If mod(i, 100000) = 0 then
Commit;
End if;
End loop;
End;
--create cust_products table
create table cust_products
(product_id number (6),
customer_id number(6),
date_purchased date);
--describe to see if table is created as required
desc cust_products
--populate cust_products with custome_id 1 to 10 and dates
Begin
For i in 1..20
Loop
Insert into cust_products
values(dbms_random.value(555,999),i,add_months('04-Nov-08',i));
If mod(i, 100000) = 0 then
Commit;
End if;
End loop;
End;
select * from cust_products
--update customer table as required
Begin
For i in 1..10
Loop
update customer set recently_purchased = 'Y';
commit;
update customer C set recently_purchased = 'N' where exists (select date_purchased from cust_products P where C.customer_id = P.customer_id );
commit;
End loop;
End;
--Insert into results table
select customer_id,count(product_id)
from cust_products
group by customer_id
Edited by: user497841 on Feb 4, 2010 2:12 PM
Similar Messages
-
PL/SQL block to create temporary table + load via cursor for loop
Assume I have a table that contains a subset of data that I want to load into a temporary table within a cursor for-loop. Is it possible to have a single statement to create the table and load based on the results of the fetch?
I was thinking something like:
Declare CURSOR xyz is
CREATE TABLE temp_table as
select name, rank, serial number from
HR table where rank = 'CAPTAIN'
BEGIN
OPEN xyz
for name in xyz
LOOP
END LOOP
What I see wrong with this is that the table would be created multiple times which is why this syntax is not acceptable. I'd prefer not to have to define the temporary table then load in two sepearte SQL statements and am hoping a single statement can be used.
Thanks!What is the goal here?
If you're just going to iterate over the rows that are returned in a cursor, a temporary table is unnecessary and only adds complexity. If you truly need a temporary table, you would declare it exactly once, at install time when you create all your other tables. You'd INSERT data into the temp table and the data would only be visible to the session that inserted it.
Justin -
Some "formula" interpreter or returning value from unnamed PL/Sql blocks
Hello,
My company is developing Payroll and HR software and we use Oracle 10G Database. For a new module we are looking for a system were the end user (power user) can put in some kind of "formula's" to define what info/figures he wants for certain calculations done by de module (the budget module calculations will be done in PL/SQL stored proc written by us).
Example: item "MonthlySalaryCost" = (BaseYearSal + TotalBonus)/12
Where BaseYearSal and TotalBonus are functions that exist our will exist in or database. The idea is that a PL/SQL proc (which will be the same for all our customers), at runtime will execute that "formula" and use the result in its further calculations. The "formulas" will be stored in a table. (I foresee of course a "formula" validation to prevent dangerous sql-injection).
My idea was to use Execute Immediate in the proc to execute the formula's and work with the results. In this approach we have to write (and foresee) all possible functions to access the data the user wants to use.
Another (more powerful) solution I think about, is seeing these "formula's" as unnamed PL/SQL blocks (stored in a table), were the end user (or consultant) can use the full power of PL/SQL (if then else, select into ..., etc..) to obtain the result he wants to return into the item.
My problem here is : how to return a value from a unnamed PL/SQL block that is executed via Execute Immediate in a stored proc ?
And a general question: what do you think of this approach ? are there others possibilities to do this ?
Thanks in advance,
Philippe.Hi,
Welcome to the forum!
This is a simple example:
Some functions to test:
CREATE OR REPLACE FUNCTION f_test1 RETURN NUMBER IS
RESULT NUMBER;
BEGIN
RESULT := 12;
RETURN(RESULT);
END f_test1;
CREATE OR REPLACE FUNCTION f_test2 RETURN NUMBER IS
RESULT NUMBER;
BEGIN
RESULT := 10;
RETURN(RESULT);
END f_test2;
CREATE OR REPLACE PACKAGE pack_test_functions IS
PROCEDURE proc_test;
END pack_test_functions;
CREATE OR REPLACE PACKAGE BODY pack_test_functions IS
PROCEDURE proc_test IS
v_sql VARCHAR2(4000);
v_result NUMBER;
BEGIN
v_sql := 'SELECT F_TEST1() + F_TEST2() FROM DUAL';
EXECUTE IMMEDIATE v_sql
INTO v_result;
dbms_output.put_line(v_result);
END proc_test;
END pack_test_functions;
/into v_result you have the result of the operation.
Regards, -
Call to concurrent program in a pl/sql block does not COMMIT data to table
I have the following PL/SQL block.
apps.create_po(x_org_id,x_document_num,x_agent_name,x_vendor_id,x_vendor_site_id,x_ship_to_location,x_bill_to_location,x_creation_date,new_isbn,new_print_key,new_unit_setup_cost,new_unit_run_cost,x_item,x_category_id,x_item_description,x_unit_of_measure,x_quantity,x_unit_price,x_ship_to_org_id,x_promise_date,x_qty_rcv_tolerance, x_deliver_to_location,x_destination_org_id, x_destination_subinventory,x_segment2,x_segment4);
COMMIT;
FND_GLOBAL.APPS_INITIALIZE(v_user_id,v_resp_id,201);
v_po_req_id := apps.fnd_request.submit_request('PO','POXPOPDOI',NULL,NULL,NULL,
NULL,'STANDARD',NULL,'Y',NULL,'APPROVED',NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
DBMS_OUTPUT.PUT_LINE('Request ID is:' || v_po_req_id);
IF v_po_req_id <> 0 THEN
dbms_lock.sleep(60);
dbms_output.Put_line('Sleep executed');
COMMIT;
select PHASE_CODE,STATUS_CODE INTO v_phase_code,v_status_code
FROM FND_CONCURRENT_REQUESTS
WHERE REQUEST_ID = v_po_req_id;
dbms_output.put_line('After commit Phase and status codes are = '||v_phase_code || v_status_code);
ELSE
ROLLBACK;
END IF;
dbms_output.put_line('New Po is' || x_document_num);
dbms_output.put_line('Quantity Is'|| x_quantity);
apps.receive_po(x_document_num,x_quantity);
v_rcv_req_id := apps.fnd_request.submit_request('PO','RVCTP',NULL,NULL,NULL,
'BATCH',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
DBMS_OUTPUT.PUT_LINE('Request ID is:' || v_rcv_req_id);
IF v_rcv_req_id <> 0 THEN
COMMIT;
DBMS_OUTPUT.PUT_LINE('COMMITED RECEIVING');
ELSE
ROLLBACK;
END IF;
Presently when this block runs, i can see the new PO number created. Commit is also successfully executed. The last output for the program is
New Po is 20651
Quantity Is 450
But due to some reason, the receiving program(receive_po) cannot retrieve the same PO from the base table.
But once this pl/sql block is complete, and i call the receving procedure from a different session, the Po is retrieved and receiving against the PO is executed successfully.
Can someone please suggest a work around ? Is the code missing something ? Since POXPOPDOI is a concurrent program which is executed as an asyncronous process, the commit statement after the call to concurent program does not work but the commit is executed only after it exits the pl/sql block.Thanks for responding.
receive_po() program just inserts the data into RCV_HEADERS_INTERFACE and RCV_TRANSACTIONS_INTERFACE tables based on the PO that is created in the previous step. So basically the new PO created has to be received and the receive_po() just inserts data into the interface tables so that RVCTP can be called after that for receiving.
Here is the code for the procedure.
SET SERVEROUTPUT ON;
--FND_GLOBAL.APPS_INITIALIZE(3,20707,201);
--Procedure for receiving interface to load data to RCV_HEADERS_INTERFACE and RCV_TRANSACTIONS_INTERFACE
CREATE OR REPLACE PROCEDURE receive_po (x_ponum IN VARCHAR2,x_quantity IN NUMBER) AS
v_vendor_site_id NUMBER;
v_vendor_id NUMBER;
v_agent_id NUMBER;
v_ship_to_organization_id NUMBER;
v_item_id NUMBER;
v_uom_code varchar2(25);
v_subinventory varchar2(25);
v_ship_to_location_id NUMBER;
BEGIN
--header information in variables
dbms_output.put_line('Entering Receiving Insert Procedure');
dbms_output.put_line('Po number ='||x_ponum||'$');
dbms_output.put_line('Quantity is ='||x_quantity||'$');
select pvsa.vendor_site_id into v_vendor_site_id
FROM po_headers_all pha,po_vendors pv, po_vendor_sites_all pvsa
where pha.vendor_id = pv.vendor_id
and pv.vendor_id = pvsa.vendor_id
and pha.segment1 = x_ponum;
dbms_output.put_line('Vendor Site ID is' ||v_vendor_site_id);
select pv.vendor_id into v_vendor_id
FROM po_headers_all pha,po_vendors pv, po_vendor_sites_all pvsa
where pha.vendor_id = pv.vendor_id
and pv.vendor_id = pvsa.vendor_id
and pha.segment1 = x_ponum;
dbms_output.put_line('Vendor ID is' ||v_vendor_id);
select plla.SHIP_TO_ORGANIZATION_ID into v_ship_to_organization_id
from PO_HEADERS_ALL pha, PO_LINE_LOCATIONS_ALL plla
where pha.PO_HEADER_ID = plla.PO_HEADER_ID
and pha.segment1 = x_ponum;
dbms_output.put_line('Ship to org is' ||v_ship_to_organization_id);
select agent_id into v_agent_id
FROM po_headers_all
WHERE segment1 = x_ponum;
dbms_output.put_line('Agent ID is' ||v_agent_id);
--printing header table information
dbms_output.put_line('vendor id is:'||v_vendor_id);
dbms_output.put_line('vendor site id is:'||v_vendor_site_id);
dbms_output.put_line('agent id is:'||v_agent_id);
dbms_output.put_line('ship to organization id is:'||v_ship_to_organization_id);
--line information in variables
--derive item id
select pla.item_id into v_item_id
from po_headers_all pha, po_lines_all pla
where pha.po_header_id = pla.po_header_id
and pha.org_id = pla.org_id
and pha.segment1 = x_ponum;
--derive uom
select pla.unit_meas_lookup_code into v_uom_code
from po_headers_all pha, po_lines_all pla
where pla.po_header_id = pha.po_header_id
and pla.org_id = pha.org_id
and pha.segment1 = x_ponum;
--derive subinventory
select pda.destination_subinventory into v_subinventory
from po_headers_all pha, po_lines_all pla,po_distributions_all pda
where pha.po_header_id = pla.po_header_id
and pla.po_header_id = pda.po_header_id
and pla.po_line_id = pda.po_line_id
and pha.org_id = pla.org_id
and pla.org_id = pda.org_id
and pha.segment1 = x_ponum;
--derive ship to location id
select ship_to_location_id into v_ship_to_location_id
from po_headers_all
where segment1 = x_ponum;
--printing transaction table details
dbms_output.put_line('item id is:'||v_item_id);
dbms_output.put_line('UOM is:'||v_uom_code);
dbms_output.put_line('subinventory is:'||v_subinventory);
dbms_output.put_line('ship to location id is:'||v_ship_to_location_id);
--insert data into the receiving interface header table
INSERT INTO RCV_HEADERS_INTERFACE
HEADER_INTERFACE_ID ,
GROUP_ID ,
PROCESSING_STATUS_CODE ,
RECEIPT_SOURCE_CODE ,
TRANSACTION_TYPE ,
LAST_UPDATE_DATE ,
LAST_UPDATED_BY ,
LAST_UPDATE_LOGIN,
CREATION_DATE ,
CREATED_BY ,
VENDOR_ID ,
VENDOR_SITE_ID ,
SHIP_TO_ORGANIZATION_ID ,
EXPECTED_RECEIPT_DATE ,
EMPLOYEE_ID ,
VALIDATION_FLAG
SELECT
RCV_HEADERS_INTERFACE_S.NEXTVAL,
RCV_INTERFACE_GROUPS_S.NEXTVAL,
'PENDING',
'VENDOR',
'NEW', -- 'CANCEL',
sysdate,
3,
3,
sysdate,
3,
v_vendor_id,
v_vendor_site_id,
v_ship_to_organization_id,
sysdate+5,
v_agent_id,
'Y'
FROM DUAL;
commit;
--insert data into the interface transaction table
for i in 1..1 loop
INSERT INTO RCV_TRANSACTIONS_INTERFACE
(INTERFACE_TRANSACTION_ID ,
HEADER_INTERFACE_ID ,
GROUP_ID ,
LAST_UPDATE_DATE ,
LAST_UPDATED_BY ,
CREATION_DATE ,
CREATED_BY ,
LAST_UPDATE_LOGIN,
TRANSACTION_TYPE ,
TRANSACTION_DATE ,
PROCESSING_STATUS_CODE ,
PROCESSING_MODE_CODE ,
TRANSACTION_STATUS_CODE ,
QUANTITY ,
UNIT_OF_MEASURE ,
ITEM_ID ,
AUTO_TRANSACT_CODE ,
RECEIPT_SOURCE_CODE ,
SOURCE_DOCUMENT_CODE ,
SUBINVENTORY ,
DOCUMENT_NUM ,
SHIP_TO_LOCATION_ID ,
VALIDATION_FLAG
SELECT
RCV_TRANSACTIONS_INTERFACE_S.NEXTVAL,
RCV_HEADERS_INTERFACE_S.CURRVAL,
RCV_INTERFACE_GROUPS_S.CURRVAL,
SYSDATE,
3,
SYSDATE,
3,
3,
'RECEIVE', --'RECEIVE', -- 'SHIP', --'06-JAN-1998',--question here
sysdate,
'PENDING',
'BATCH',
'PENDING',
x_quantity,
v_uom_code,
v_item_id,
'DELIVER', -- 'RECEIVE', --'DELIVER',
'VENDOR',
'PO',
v_subinventory,
x_ponum,
v_ship_to_location_id,
'Y'
FROM DUAL;
end loop;
commit;
END receive_po;
I am really stuck and looking out for work arond. Please help.
Thanks,
Natasha -
How to Populate a table in PL/SQL
Hi Every1,
please clarify me How to Populate a table in PL/SQL,Thanx in advance...
Thanks & Regards,
Ram Nainar SNot possible. SQL is used to populate tables - it is the language that interacts (CRUD) Oracle data in tables. Not PL/SQL.
So even when using PL/SQL, you still need to use SQL. Thus "populating" a table is no different than using SQL or using SQL (from inside PL/SQL). -
Pl/sql block reading reading table data from single point in time
I am trying to figure out whether several cursors within a PL/SQL block are executed from within a Single Point In Time, and thus do not see any updates to tables made by other processes or procedures running at the same time.
The reason I am asking is since I have a block of code making some data extraction, with some initial Sanity Checks before the code executes. However, if some other procedure would be modifying the data in between, then the Sanity Check is invalid. So I am basically trying to figure out if there is some read consistency within a PL/SQL, preventing updates from other processes to be seen.
Anyone having an idea?.
BR,
Cenk"Transaction-Level Read Consistency
Oracle also offers the option of enforcing transaction-level read consistency. When a transaction runs in serializable mode, all data accesses reflect the state of the database as of the time the transaction began. *This means that the data seen by all queries within the same transaction is consistent with respect to a single point in time, except that queries made by a serializable transaction do see changes made by the transaction itself*. Transaction-level read consistency produces repeatable reads and does not expose a query to phantoms."
http://www.oracle.com/pls/db102/search?remark=quick_search&word=read+consistency&tab_id=&format=ranked -
Alter table then Update in PL/SQL block
I am trying to alter the table then update it :
declare
colCount number;*
begin*
select count(*) into colCount from all_tab_cols where table_name = 'TEST' and owner = 'TEST_OWNER';*
dbms_output.put_line('No of Columns in the table : ' || colCount);*
if colCount = 2 then*
dbms_output.put_line('Table needs upgrade');*
execute immediate('ALTER TABLE TEST ADD COL1 VARCHAR2(100) NULL');*
UPDATE TEST SET COL1 = '123';*
commit;*
else*
dbms_output.put_line('No Changes Required');*
end if;*
end;*
Oracle complains that "COL1" is an invalid identifier.
I also tried substitute the UPDATE statement with
** execute immediate('UPDATE TEST SET VCHCHARSET_OUT='UTF8' WHERE VCHCHARSETNAME='UTF8'');**
and there is something wrong with the construction of an Update statement in the parenthesis.
Am I taking the right approach and just need to figuire out the syntax of single quotes or something else is wrong?
thanks in advance.Yes, you are absolutely right, I shouldn't alter the table and then update the values.
The reason I need to do it relates to the migration process we utilize in our company. Initially I had a set of SQL commands which I executed migrating from one environment to another and eventually to Production. I had an error in the last SQL command which caused migration process to produce "Failure", however the table was already altered and all the rows except the last one were updated. Since I can't successfully migrate to Production with the failed process I have to generate a PL/SQL block which will take in consideration that in one environment the table has already been modified and in the other one is still needs to be changed. -
Temporary table in a pl/SQL block
Hi all. I am in the process of learning PL/SQL and right now I focusing on Temporary Tables & PL/SQL blocks. without going into great detail I have created a cursor for loop that will retrive records from a table based on my criteria. I now need to insert this information into a temporary table. I am somewhat familiar on the usage of a temporary table by itself but I am confused by its usage in the PL/SQL block itself. For example, does it need to be declared?
pl/SQl block or PL/SQl table(associate array) ?
this example will help, if i got is correct
SQL> declare
2 cur_emp sys_refcursor;
3 type t_obj is record( empno number, ename varchar2(25));
4 type t_tab is table of t_obj index by binary_integer;
5 tt t_tab;
6 begin
7 open cur_emp for
8 select empno,ename from emp where deptno=10;
9 loop
10 fetch cur_emp BULK collect into tt;
11 exit when cur_emp%notfound;
12 end loop;
13 for i in 1..tt.count loop
14 dbms_output.put_line('empno :' ||tt(i).empno||' ename :'||tt(i).ename);
15 end loop;
16 end;
17 /
empno :7782 ename :CLARK
empno :7839 ename :KING
empno :7934 ename :MI_LL_ER
PL/SQL procedure successfully completed. -
Creating temporary table in pl/sql block problem
hello
i have a problem in creating and using temporary table in pl/sql block
please verify below block
begin
execute immediate 'create global temporary table alitemp1 (co_t varchar2(10),color varchar2(10))';
insert into alitemp1 (co_t,color) values ('001','red');
execute immediate 'DROP TABLE alitemp1';
end;
when i execute that block i will receive this error
insert into alitemp1 (co_t,color) values ('001','red');
ERROR at line 3:
ORA-06550: line 3, column 14:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 3, column 2:
PL/SQL: SQL Statement ignored
i think it because that alitemp1 table don't create
but two below block run fine
begin
execute immediate 'create global temporary table alitemp1 (co_t varchar2(10),color varchar2(10))';
execute immediate 'DROP TABLE alitemp1';
end;
begin
execute immediate 'create global temporary table alitemp1 (co_t varchar2(10),color varchar2(10))';
end;
select table_name from user_tables where table_name='ALITEMP1';
TABLE_NAME
ALITEMP1
it means that problem is when the below line exists in block
insert into alitemp1 (co_t,color) values ('001','red');
if may please guide meIn addition to the comments by Justin and 3360, you cannot do what you want the way you are doing it.
All objects referred to in a PL/SQL block must exist at the time the block is compiled. In your case, since it is an anonomous block, that is run time. Since you are dynamically creating the temporary table you need to refer to it dynamically as well. More like:
BEGIN
EXECUTE IMMEDIATE 'create global temporary table alitemp1 (co_t varchar2(10),
color varchar2(10))';
EXECUTE IMMEDIATE 'insert into alitemp1 (co_t,color) values (:b1,:b2)' USING '001', 'red';
EXECUTE IMMEDIATE 'DROP TABLE alitemp1';
END;However, don't do that it is a really bad idea. Just create the temporary table, if you really need it, once and use it in your processing.
In most cases, things that SQL Server needs temporary tables for can be done easily in Oracle with a single SQL statement,
John -
SQL> create type string_table is table of varchar(100);
2 /
Type created.
declare
v_names string_table := string_table();
begin
v_names.EXTEND(3);
v_names(1) := 'name1';
v_names(2) := 'name2';
v_names(3) := 'name3';
dbms_output.put_line(v_names(1));
dbms_output.put_line(v_names(2));
dbms_output.put_line(v_names(3));
dbms_output.put_line(v_names.COUNT());
select * from table(v_names);
end;
select * from table(v_names);
ERROR at line 12:
ORA-06550: line 12, column 7:
PLS-00428: an INTO clause is expected in this SELECT statementselect * from table(v_names);
I guess ,here you were trying to put the content of the NT into another NT, or just trying to print it.
But, I don't think INTO Clause is mandatory here.
Please check your modified code (w/o INTO) and the output :
DECLARE
TYPE string_table IS TABLE OF VARCHAR (100);
v_names string_table := string_table ();
v_test string_table := string_table ();
BEGIN
v_names.EXTEND (3);
v_names (1) := 'name1';
v_names (2) := 'name2';
v_names (3) := 'name3';
DBMS_OUTPUT.put_line ('Old collection - '||v_names (1));
DBMS_OUTPUT.put_line ('Old collection - '||v_names (2));
DBMS_OUTPUT.put_line ('Old collection - '||v_names (3));
DBMS_OUTPUT.put_line ('Old collection - '||v_names.COUNT ());
DBMS_OUTPUT.put_line (CHR(10));
/* SELECT * FROM TABLE (v_names); */
v_test := v_names;
DBMS_OUTPUT.put_line ('New collection -- '||v_test (1));
DBMS_OUTPUT.put_line ('New collection -- '||v_test (2));
DBMS_OUTPUT.put_line ('New collection -- '||v_test (3));
DBMS_OUTPUT.put_line ('New collection -- '||v_test.COUNT ());
DBMS_OUTPUT.put_line (CHR(10));
/* Printing using FOR LOOP */
FOR i IN v_test.FIRST..v_test.LAST
LOOP
DBMS_OUTPUT.put_line ('In FOR Loop --- '||v_test (i));
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error ' ||SQLERRM|| DBMS_UTILITY.format_error_backtrace);
END;gives o/p :
Old collection - name1
Old collection - name2
Old collection - name3
Old collection - 3
New collection -- name1
New collection -- name2
New collection -- name3
New collection -- 3
In FOR Loop --- name1
In FOR Loop --- name2
In FOR Loop --- name3Refer this link -- http://docs.oracle.com/cd/E11882_01/appdev.112/e17126/tuning.htm#CIHGGBGF
Edited by: ranit B on Dec 26, 2012 2:29 PM
-- code modified
Edited by: ranit B on Dec 26, 2012 2:45 PM
-- code 'again' updated -- FOR LOOP added -
Pl/sql block is too slow, should procedure a better option
Hi all,
how to tune A PL/SQL block that traverse cursors and fetch millions of records then execute inserts in different tables,
using execute immediate statement.
It's too slow and takes 10 hours to populate 40 tables having millions of records,
as i have to do some modifications in data so can not do it by CTAS,
i.e. a single sql statement.
Should i make a procedure, does it help .
Please help or suggest As i am New to PL/Sql
My code look like,
declare
cursor cur_table1 is
select field1,field2,field3,field4 from table1;
begin
for i in cur_table1
loop
execute immediate 'insert into table2 (field1,field2,field3,field4) '||
'select :1,field2,field3,field4 '||
' from table1 where field3= :2'
using i.field1||'_'||to_char(sysdate,'ddmmyyyy hh12:mi:ss',i.field1;
commit;
end if;
end;
Thanks and Regards,declare
cursor cur_projects is
select PROJECTID, PROJECTNAME, DESCRIPTION, DELETED, DELETINGDATE, ACTIVE, ADMINONLY, READONLY, SECURITYCLASS, PROJECTCONTACT, DEFAULTVERSION, DEFAULTSTARTPAGE, IMAGEPATH, MAXEXAMINEERRORS, LOCKTIMEOUT, MEMORYSAVINGLEVEL, PRELOADOBJECTS, PUBLICATIONSRCPROJNAME, CREATOR, CREATED, MODIFIER, MODIFIED from projects ;
cursor cur_projectversion(p_projectid projects.projectid%TYPE) is
select PROJECTID, PROJECTVERSIONID, PROJECTVERSIONNAME, DESCRIPTION, DELETED , DELETINGDATE, ACTIVE , ADMINONLY, READONLY, decode(EFFECTIVEDATE,null,trunc(sysdate),EFFECTIVEDATE) EFFECTIVEDATE, EXPIRATIONDATE, SECURITYCLASS, PROJECTCONTACT, DEFAULTVERSION, DEFAULTSTARTPAGE, IMAGEPATH, MAXEXAMINEERRORS, LOCKTIMEOUT, MEMORYSAVINGLEVEL, PRELOADOBJECTS, PUBLICATIONSRCPROJNAME, PUBLICATIONSRCPROJVERNAME, CREATOR, CREATED, MODIFIER, MODIFIED, PROFILELOADERCLASS /*, TRACKCHANGES */
from projectversions where PROJECTID=p_projectid ;
cursor cur_objects(p_projectid projects.projectid%TYPE,p_projectversionid projectversions.projectversionid%TYPE) is
select PROJECTID , PROJECTVERSIONID, OBJECTID , OBJECTKEY , PARENTID, KIND , NAME , TITLE , OWNER , CREATED, MODIFIER , MODIFIED , READY_TO_PUBLISH, LAST_PUBLISHED_DATE , LAST_PUBLISHER , EFFECTIVE_PUBLISHING_DATE , PUBLISHER , PUBLISHING_DATE /*, to_lob(scripttext) */ from OBJECTS where PROJECTID=p_projectid and PROJECTVERSIONID=p_projectversionid /*order by objectid */;
begin
for i in cur_projects
loop
dbms_output.put_line('PROJECTID => '||i.projectid);
dbms_output.put_line('_________________________________');
execute immediate 'insert into &TARGET_USER\.projects(locktimeout, memorysavinglevel , preloadobjects, projectid, projectname, description, deleted, deletingdate, active, adminonly, readonly, securityclass, projectcontact, defaultversion, defaultstartpage, imagepath, maxexamineerrors ) values (:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17) '
using i.locktimeout, i.memorysavinglevel, i.preloadobjects,i.projectid ,i.projectname , i.description , i.deleted , i.deletingdate , i.active , i.adminonly , i.readonly, i.securityclass, i.projectcontact , i.defaultversion, i.defaultstartpage , i.imagepath, i.maxexamineerrors;
for k in cur_projectversion(i.projectid)
loop
for l in cur_objects(k.projectid,k.projectversionid)
loop
cnt:=cnt+1;
select count(1) into object_exists from &TARGET_USER\.objects where objectid=l.objectid and projectversionid=1 and projectid=l.projectid;
if object_exists = 0
then
if l.objectid = 1 ------Book Object , objectid = 1 and parentid = 0
then
execute immediate 'INSERT INTO &TARGET_USER\.objects(PROJECTID,PROJECTVERSIONID,OBJECTID, OBJECTKEY,PARENTID,NAME, KIND,LAST_PUBLISHED_DATE,LAST_PUBLISHER,REVISIONID,DISPLAYORDER,READONLY,DELETED) values( :1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13)'
using l.PROJECTID, 1, l.OBJECTID,l.OBJECTKEY, 0 , l.NAME,l.KIND, '' , '' , '', 0, 'N', 'N';
else
select count(1) into object_parentid_exists from objects where objectid=l.parentid and projectversionid=1 and projectid=l.projectid;
if object_parentid_exists = 0 ---Set Parentid as 1
then
cnt_parentid_1:=cnt_parentid_1+1;
execute immediate 'INSERT INTO &TARGET_USER\.objects(PROJECTID,PROJECTVERSIONID,OBJECTID, OBJECTKEY,PARENTID,NAME, KIND,LAST_PUBLISHED_DATE,LAST_PUBLISHER,REVISIONID,DISPLAYORDER,READONLY,DELETED) values( :1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13)'
using l.PROJECTID, 1, l.OBJECTID,l.OBJECTKEY, 1 , l.NAME,l.KIND, '' , '' , '', 0, 'N', 'N';
else
execute immediate 'INSERT INTO &TARGET_USER\.objects(PROJECTID,PROJECTVERSIONID,OBJECTID, OBJECTKEY, PARENTID, NAME, KIND,LAST_PUBLISHED_DATE,LAST_PUBLISHER,REVISIONID,DISPLAYORDER,READONLY,DELETED) values( :1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13)'
using l.PROJECTID, 1, l.OBJECTID,l.OBJECTKEY,l.PARENTID,l.NAME,l.KIND, '' , '' , '', 0, 'N', 'N';
end if;
end if ;
end if;
execute immediate 'INSERT INTO &TARGET_USER\.objectversions( PROJECTID, OBJECTID, PROJECTVERSIONID ,VERSIONNAME,OBJECTVERSIONID, REVISIONID,DESCRIPTION, TITLE , OWNER, CREATED, MODIFIER, MODIFIED, READY_TO_PUBLISH , LAST_PUBLISHED_DATE, LAST_PUBLISHER, EFFECTIVEDATE, SCRIPTTEXT, REVIEWSTATUS, READONLY, PUBLISHED, DELETED ) '||
'SELECT PROJECTID, OBJECTID, 1, owner||:1, PROJECTVERSIONID , '''', '''', TITLE, OWNER, CREATED, MODIFIER, MODIFIED, ''N'', '''' , '''', :2 , to_lob(SCRIPTTEXT), '''', ''N'', ''N'', '''' '||
'FROM OBJECTS '||
'WHERE PROJECTID= :3 and PROJECTVERSIONID= :4 and OBJECTID= :5'
using '_'||TO_CHAR(k.EFFECTIVEDATE,'DDMMYYHHMISS'),k.EFFECTIVEDATE,l.projectid,l.projectversionid,l.objectid;
end loop;
dbms_output.put_line(cnt||' OBJECTS, OBJECTVERIONS POPULATED');
dbms_output.put_line(cnt_parentid_1||' DUMPED UNDER BOOK FOLDER ');
cnt_parentid_1:=0;
cnt:=0;
............ -
SQL logic help for pl/sql block
Hi All,
I need your suggestions and comments for the below issue:
I have two tables: table A and table B
Table A has two columns as id and counts:
Id Counts
99 10
999 13
9999 7
Table B has two columns as Id and order:
Id Order
99 1
999 2
9999 3
We need to update Order in Table B such that Id having highest count in table A has Order as 1 in table B and it keep on increasing the order for other Ids based on decreasing counts in table A. This will be like a job which will run daily and look for counts in table A and update Order in table B according to it.
It seems to be simple but i am not getting it. Please help me out of this by writing some PL/SQL block.
I will really appreciate your all comments and responses.
Regards
DevHi,
Keen2Learn wrote:
Hi All,
I am really greatful to all fo you for all your replies and comments. I change ORDER table to ORDERS. All you replies worked for me but there is some slight change in scenario which i need to discuss with you all.
E.g: Table A has 10 rows like below:
Id Counts Type
99 10 A
999 13 A
9999 7 C
99 4 B
999 2 C
88 2 A
77 1 C
777 3 B
777 5 A
888 2 CIf you'd like help, please post CREATE TABLE and INSERT statements for your sample data (including table b as it is before the UPDATE or MERGE).
I populate data in Orders column Table B based on id, by grouping sum of counts for that id in table A.
Id 999 has highest sum(count) as 15, so it has orders as 1 in Table B and do same for descending counts for each Id.
Table B has 5 rows like below:
Id Orders
99 2
999 1
88 4
777 3
555 5
Assume Table B as static(no new record comes in it) but only its Orders changes for each Id based on counts for that Id in Table A. As you see, Table B has id 555 which is not in Table A, so we need to update its orders to the highest number by taking its Count as 0(zero). Sorry, it's unclear what you want to do.
Post what you'd like table b to look like after the UPDATE or MERGE.
Right now i am doing it like this:
declare
cursor c1 is
select Id, SUM (COUNT), RANK () OVER (ORDER BY SUM (COUNT)) rnk
from TableA AND Id IN (SELECT Id FROM TableB)
GROUP BY Id
ORDER BY rnk DESC;
i NUMBER := 1;
begin
for curr in c1
loop
update TableB
set orders = i
where id = curr.id;
i := i + 1;
end loop;
end;I'm not sure what you're trying to do, but I'll bet you don't need PL/SQL to do it. Use a single UPDATE or MERGE statement (inside PL/SQL if necessary).
But it is not updating orders for Id 555 in TableB.There is no row for id=555 in table b, and, according to your requirements, there never will be, because "Table B as static(no new record comes in it)". It's behaving exactly as you said you wanted it to. What's the problem?
Please provide your suggesstions on what needs to be done to take care of this scenario. I will really appreciate your all suggesstions and comments. Please let me know if need some more explanation.Whenever you have a problem, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only), and the results you want from that data.
In the case of a DML operation (such as UPDATE) the sample data should show what the tables are like before the DML, and the results will be the contents of the changed table(s) after the DML.
Explain, using specific examples, how you get those results from that data.
Always say what version of Oracle you're using. -
ORA-06550 - while compiling the PL/SQL block.
I am trying a to populate a table based on the below pl/sql block
Declare
temp source.source%type;
tregion varchar2(40);
tversion varchar2(40);
tsource varchar2(100);
Cursor c1 is
Select * from Source;
Begin
Open c1;
Loop
fetch c1 into temp;
select REGION, VERSION, SOURCE into tregion, tversion, tsource from QUOTE_LETTERS_MASTER where SOURCE = temp AND REGION = 'eSource';
insert into esource values(tregion, tversion, tsource);
Exception
when no_data_found then
insert into esource values('No eSource',' ',temp.source);
exit when c1%notfound;
End Loop;
close c1;
end;yes, there are more than one rows that is returned when i do a Select Into statement.
I am trying to resolve by using a cursor C2 inside the already existing cursor C1, i will use a inner loop to get the select statement value to cursor c2 then i will assign the vlaues the variables, then once i read all the values of cursor c2 i will exit inner loop and go to outer loop to read the next value of c1 and then again go to cursor c2 and inner loop.
Do you think it will work ?
Thank you,
rakesh
I have pasted the code below.
Declare
temp1 source.source%type;
temp2 QUOTE_LETTERS_MASTER%rowtype;
Cursor c1 is
Select * from Source;
Begin
open c1;
loop
fetch c1 into temp;
cursor c2 is
select region, version, source from QUOTE_LETTERS_MASTER where SOURCE = temp AND REGION = 'eSource';
open c2;
loop
begin
fetch c2 into temp2;
insert into esource values(temp2.region, temp2.version, temp2.source);
Exception
when no_data_found then
insert into esource values('No esource',' ',temp);
exit when c2%notfound;
end loop;
close c2;
exit when c1%notfound;
end loop;
close c1;
end;
But is giving this error : - ORA-06550: line 10, column 13:
***PLS-00103: Encountered the symbol "C2" when expecting one of the following:
***:= . ( @ % ;
***1. Declare***
***2. temp1 source.source%type;
***3. temp2 QUOTE_LETTERS_MASTER%rowtype;
Edited by: rakesh119 on Apr 10, 2013 11:08 AM -
Display an Alert message in PL/SQL block in APEX
Hi,
we are getting an oracle exception while inserting a new row. As it is having the unique constaint on a coulumn.
Now the problem iis we need to Display an "Alert message" based on the input field validation. That java script code for alert has to be embeded nside a PL/SQL block in Oracle APEX Application.
we tried doing this with below code:
Begin
INSERT INTO <<table name>>(ID,NAME) VALUES (s1,:TXT_s2);
exception when others then
htp.p('<script language="javascript">');
htp.p('alert("Exception");');
htp.p('</script>');
end;
If anybody knows .... please reply.
Thanks,
Subarna
Edited by: user9955252 on Apr 21, 2010 1:47 AMHello,
APEX Forum is here : Oracle Application Express (APEX)
Regards -
Display an Alert message from PL/SQL block in APEX
Hi,
we are getting an oracle exception while inserting a new row. As it is having the unique constaint on a coulumn.
Now the problem iis we need to Display an "Alert message" based on the input field validation. That java script code for alert has to be embeded nside a PL/SQL block in Oracle APEX Application.
we tried doing this with below code:
Begin
INSERT INTO <<table name>>(ID,NAME) VALUES (s1,:TXT_s2);
exception when others then
htp.p('<script language="javascript">');
htp.p('alert("Exception");');
htp.p('</script>');
end;
If anybody knows .... please reply.
Thanks,
SubarnaIf your end goal is showing a pretty error message instead of the message that the tables unique constraint raises try the following. This logic will show a nice message and not try to insert non-unique data.
(1) Create a validation of type "Function Returning Error Text".
(2) Place similar code like the following in your validation. Notice that if the unique name does not exist the no_data_found returns null allowing the validation to pass.
DECLARE
v_error varchar2(100);
BEGIN
SELECT 'A person by this name already exists.'
INTO v_error
FROM your_table
WHERE your_name = :P1_YOUR_NAME;
RETURN v_error;
EXCEPTION
WHEN no_data_found THEN
RETURN NULL;
END;
Maybe you are looking for
-
How do I update SilverFast software without optical drive
SilverFast scanning software requires the original media be in the opticall drive in order to upgrade to an new version or install a downloaded version. Any ideas how to transfer installed software or neccessary files from another Mac to my new 2012
-
Error message when running HD-DVD player after clean win 7 install on P205-S6347
On a P205-S6347, did clean win 7 ultimate install with toshiba instructions and loadup software downloaded from toshiba support. On first dvd player install of latesed full player, got a video eror. Installed latets patch, now I get "An error has o
-
Parent / Child Groups in Portal with LDAP
Heya, we are using EP 7 on SP 10 (NW 7), for User Authentication we use the UME with a configured (writable) LDAP Server as backend with a flat hierarchie. We have a Federated Portal Landscape with 3 Portals connected to one "main" portal and using R
-
D: Dynamic date calculation
Hello, In BEx, when creating a variant, is it possible to use "Selection variable = D: Dynamic date calculation"? I have created a variable for 0calmonth and in the Variant Attributes screen, Selection variable field, the only option is T: Table Vari
-
Connect to networked OFFICE Jet Pro 7680 device in windows 7 64 bit system.
The system Can't find the OFFICE Jet Pro 7680 device in windows 7 64 bit system. I am unable to use my scanner. I tried to add the device from the devices and printers screen. The device is wired to a port on the router, but the system can not fin