Professional Documents
Culture Documents
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Questions
Home > Question Details
Resources
Archives
Links
Popular
Hot
Files
Munzer -- Thanks for the question regarding "Collection Variable Types", version 8.1.7
Submitted on 24-Mar-2002 21:52 Central time zone Last updated 28-Dec-2010 10:24 Tom's latest followup | Bookmark | Bottom
You Asked
Tom: What is really the difference and when you would use each of oracle datatypes: 1. 2. 3. Index-by-tables Nested Tables Varrays
My understanding is that index by tables are for data of same type that is stored in memory. For nested tables you can store the variables values in oracle table. Varrays are same as nested except they are confined to a certain number. AM I correct? Would you use a nested table for two tables like a PO table and items table iinstead of referring to two tables. Thank you,
and we said...
The major difference between: (index by tables) and (nested tables/varrays) is that index by tables are only available in PLSQL, nested tables/varrays are avaialable in both PLSQL *and* SQL. Index by tables are basically "sparse" arrays that need no allocation. ops$tkyte@ORA817DEV.US.ORACLE.COM> declare 2 type array is table of number index by binary_integer; 3 data array; 4 begin 5 data(1000) := 1; 6 end; 7 / PL/SQL procedure successfully completed. Here plsql gladly accepts an entry in the 1,000'th slot -- without doing anything else. There is nothing in slots 1, 2, ... 999 (or 1001 or -1, -2,.... ) That array has allocated space for 1 element in the 1,000th position. tables/varrays do not behave that way: ops$tkyte@ORA817DEV.US.ORACLE.COM> declare 2 type array is table of number ; 3 data array := array(); 4 begin 5 data(1000) := 1; 6 end; 7 / declare * ERROR at line 1: ORA-06533: Subscript beyond count ORA-06512: at line 5 Nested For example:
1 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Here it is saying "you haven't allocated me any space up there...". .extend attribute: ops$tkyte@ORA817DEV.US.ORACLE.COM> declare 2 type array is table of number ; 3 data array := array(); 4 begin 5 data.extend(1000); 6 data(1000) := 1; 7 end; 8 / PL/SQL procedure successfully completed. and we can do so. Note that we do have to allocate 1,000 entries: ops$tkyte@ORA817DEV.US.ORACLE.COM> declare 2 type array is table of number ; 3 data array := array(); 4 begin 5 data.extend(1); 6 data(1000) := 1; 7 end; 8 / declare * ERROR at line 1: ORA-06533: Subscript beyond count ORA-06512: at line 6 the nested table/varray type isn't "sparse" like the index by table.
Day to day, in plsql code, i generally use index by tables exclusively. They are a little faster, a little more flexible. It is when I need to use the table type in SQL that I use a nested table (see http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:110612348061 for an example of what I mean by that).... There are other differences between varrays and nested tables when you use them for storage in a database table. For example -- varrays maintain their "order". Nested tables do not. Varrays are stored in lobs -- nested tables in separate tables. There are certain DML operations available for nested tables that are not avaialable for varrays. See http://download-west.oracle.com/docs/cd/A87860_01/doc/appdev.817/a76976/toc.htm for more details.
Reviews March 28, 2002 - 2am Central time zone Reviewer: Helena Markova from Bratislava, Slovakia Bookmark | Bottom | Top
March 28, 2002 - 1pm Central time zone Reviewer: Arun Panchal from Rahway, NJ
Need Help!!! August 3, 2003 - 9am Central time zone Reviewer: Suwarna from Manchester, UK Hi Tom,
Sorry for not following your procedures/policies. Was really needing your help and hence added my query to Collection types question. I have three tables. Structure of each is: Cash: This table holds all payments made by customers by date by account_reference. Columns are: cash_id number(22) Primary Key, receipt_date date, account_reference_number varchar2(13),
2 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
cash_amount number(22,2) Charge: This table holds all the charges raised against the products(Water, Sewerage, etc) provided by Water system to the customers. Columns are: charge_id number(22) Primary Key, activity_date date, account_reference_number varchar2(13), billable_amount number(22,2) charge_type number(22) Cash_Application: This table holds combination of cash_id and charge_id for an account_reference with the cash_amount received for each charge. Columns are: cash_application_id number(22) Primary Key, fk_cash_id number(22), fk_charge_id number(22), account_reference_number varchar2(13), applied_amount number(22,2) Now, Cash_Application table needs to be loaded using Cash and Charge tables recursively. There are some rules to do cash allocation for each charge. 1. The earliest cash will be allocated to the earliest charge 2. If there are more than one charge records on the same date, then cash will be allocated in proportionally to each charge.Thus if cash_amount is x and there are three charges a, b and c, cash applied to each charge will be x*a/(a+b+c), x*b/(a+b+c), x*c/(a+b+c), respectively. There are two possibilities .... i.billable_amount for each charge will become zero after allocating the cash ii. cash will be insufficient for sum(billable_amount) for an account_reference on a particular date. In first case, if some more charges exist for the account, cash will be applied to those charges In second case, new cash record will be brought in from cash table and it will be allocated proportionally to remaining charges 3. Any cash that remains after fully allocating all the charges on the account for all days, will remain un-allocated Please guide on how this can be done using PL/SQL. Thanks a ton!!! Regards, Suwarna.
I will do the coding as I am here for that .... August 3, 2003 - 9am Central time zone Reviewer: A reader Hi,
Thanks for going through the question. I really want to do the coding ... but not really knowing from where to start. Some pointers on this will be really appreciated. Have tried doing this using varray and using normal cursors. But getting messed up. Thought you can help me out (not very good of me expecting such a thing, but still thought!!!) Regards, Suwarna
3 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Bookmark | Bottom | Top Reviewer: Reader Hi Tom, Will you please give an example for 'bulk collect the data into arrays of records from a table'?
I am gettin ORA error August 7, 2003 - 5am Central time zone Reviewer: Reader from UK Hi Tom,
I tried the above example by creating a record type and then table of records. Following is the code and error messages .... SQL> ed Wrote file afiedt.buf 1 declare 2 type cash_Rec is record (account_reference_number char(13), cash_id number(22), cash_amount decimal(22,2)); 3 type cash_Tab is table of cash_Rec index by binary_integer; 4 l_cashTab cash_Tab; 5 cursor cashCursor is 6 select acc_ref_num, pk_cash_id, amount 7 from cash 8 order by acc_ref_num, rcpt_dt; 9 l_counter integer := 10; 10 begin 11 open cashCursor; 12 fetch cashCursor bulk collect into l_cashTab limit l_counter; 13 close cashCursor; 14* end; SQL> / fetch cashCursor bulk collect into l_cashTab, l_cashTab, l_cashTab limit l_counter; * ERROR at line 12: ORA-06550: line 12, column 40: PLS-00597: expression 'L_CASHTAB' in the INTO list is of wrong type ORA-06550: line 12, column 5: PL/SQL: SQL Statement ignored Where am I going wrong????
4 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
12 13 14
PL/SQL procedure successfully completed. why do you have three tables in your into clause? you only need one.
Corrections .... August 8, 2003 - 11am Central time zone Reviewer: A reader from Manchester, UK Some corrections to above code ....:)) SQL> ed Wrote file afiedt.buf 1 declare 2 type cash_Rec is record (account_reference_number char(13), cash_id number(22), cash_amount decimal(22,2)); 3 type cash_Tab is table of cash_Rec index by binary_integer; 4 l_cashTab cash_Tab; 5 cursor cashCursor is 6 select acc_ref_num, pk_cash_id, amount 7 from cash 8 order by acc_ref_num, rcpt_dt; 9 l_counter integer := 10; 10 begin 11 open cashCursor; 12 fetch cashCursor bulk collect into l_cashTab limit l_counter; 13 close cashCursor; 14* end; SQL> / fetch cashCursor bulk collect into l_cashTab limit l_counter; * ERROR at line 12: ORA-06550: line 12, column 40: PLS-00597: expression 'L_CASHTAB' in the INTO list is of wrong type ORA-06550: line 12, column 5: PL/SQL: SQL Statement ignored Where am I going wrong????
Using 9.2 Oracle version August 11, 2003 - 4am Central time zone Reviewer: Su from Manchester, UK Hi Tom,
Oracle version is 9.2. Are some added privileges required to create arrays in the schema? Regards.
5 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Example for sequentially accessing records in an Array August 11, 2003 - 4am Central time zone Bookmark | Bottom | Top Reviewer: Reader Hi Tom, Will you please give an example of how the records loaded by above example can be fetched or read sequentially and some manipulations done on the data. Thanks and regards, A reader
Upper limit on collection types September 2, 2003 - 6pm Central time zone Reviewer: BK from NJ USA
Very good explanation, I still have one more doubt in my mind. What's the upper limit on different collection types? If dependent on hardware then what would be upper limit on a server with 1GB of RAM. I'm considering collecting around 50K records into a table type and passing this table to a procedure for dumping into a file. Would this approach be faster than writing to the file directly. Your insight is greatly appreciated. Thanks,
need more explanation on upper limit of collection type September 18, 2003 - 11pm Central time zone Bookmark | Bottom | Top Reviewer: BK from NJ Tom, Could you elaborate on why you would not be comfortable with this approach. We have taken this approach keeping 4-5 thousand records per day in mind. Now program has to handle Initial load of 350K records, which was not anticipated. We have modularize our code and all our interfaces creates table type and one program takes care of writing to the file. Now if we want to follow 'Get few' and 'write few' approach, we are missing the last records. Here is the eg. declare TYPE varchar_table_type IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER; v_pac_table varchar_table_type; filedir varchar2(100) := '/u226/appl/aicdappl/11.5.0/data/outbound'; v_filename varchar2(50) := 'append_file.txt'; x_status varchar2(240); x_msg varchar2(240); cursor c1 is select rownum||'-'||owner||'.'||object_name rec
6 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
from all_objects where owner = 'AR' and object_type = 'TABLE' and rownum < 53; begin for x in c1 loop v_pac_table(v_pac_table.count+1) := x.rec; dbms_output.put_line('Count : '||v_pac_table.count); IF (MOD(v_pac_table.count,10) = 0) Then interface_util.create_file(filedir, v_filename, v_pac_table, x_status, x_msg); v_pac_table.delete; END IF; end loop; dbms_output.put_line('X_Status: '||x_status); dbms_output.put_line('X_msg: '||x_msg); end; create file procedure opens file in an 'A' mode and writes data to the file. In this case how do we write the last two records ? Also I would greatly appreciate your input on optimum number of records each collection type can handle. Thanks,
Please provide more information September 22, 2003 - 12pm Central time zone Reviewer: BK from NJ, USA
Hi Tom, I wish I could reply before you could read my previous question. Tried for two days but couldn't access the site. It was very 'stupid' to ask, because it was so simple, I wasn't thinking right and I apologize for wasting your time. Your replys to the questions asked have greatly influenced my design and coding approach. I vist this site atleast once a day. Great job Tom. As you have always done could you also please explain what 'unanticipated' things can happen and why. How do I find out optimum number of records each collection type can handle, I think Oracle community will better understand when to use what collection type. Thanks,
January 17, 2004 - 5am Central time zone Reviewer: huss Dear Tom, in this example 1 declare 2 type emp is record (name varchar2(50),id number(3)); 3 type emp_Tab is table of emp index by binary_integer; 4 emps_list1 emp_tab; 5 emps_list2 emp_tab; begin ... ...
7 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
... -- I can do that emps_list1:= emps_list2 ; -- but it gives me error when try to do that if ( emps_list1 = emps_list2) then .... so , while that not work , how can i compare between the 2 tables of recored without loop inside them and compare it's fields one by one .
what is index by binary integer February 2, 2004 - 3am Central time zone Reviewer: A reader Hi What is the difference between type l_array is table of varchar2(256); type l_array is table of varchar2(256) index by binary integer; which is faster? When should index by binary integer used?
One (collection) needs to be "extended" to allocate space, the other does not. l_coll.extend; l_coll(1) := 'foo'; l_tab(1) := 'bar';
One (collection) can be initialized easily, the other -- not: l_coll := collection_type( 'hello', 'world', 'foo', 'bar' ); l_tab(1) l_tab(2) l_tab(3) l_tab(4) := := := := 'hello'; 'world'; 'foo'; 'bar';
Those are the "major" differences -- I find plsql table types generally "easier" to use since they need not be extended and "contigous" (eg: in order to have l_coll(100) - I must have 1..99 allocated. In order to have l_tab(100) i only need that entry)
Why is this bulk collect behaving like this in Oracle 9i? February 12, 2004 - 4am Central time zone Bookmark | Bottom | Top Reviewer: Raj from India Dear Tom, Sorry for posting this here instead of waiting for you to be ready for taking further questions but can you tell me why the first code executed without errors but second doesnot?
8 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
SQL*Plus: Release 9.0.1.0.1 - Production on Thu Feb 12 14:59:07 2004 (c) Copyright 2001 Oracle Corporation. Enter user-name: scott@testsystem Enter password: Connected to: Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production With the Partitioning, OLAP and Oracle Data Mining options JServer Release 9.2.0.1.0 - Production SQL> 2 3 4 5 6 7 8 9 10 declare type emparray is table of emp%rowtype index by binary_integer; cursor c1 is select * from emp; rowarray emparray; begin open c1; fetch c1 bulk collect into rowarray limit 100; close c1; end; / All rights reserved.
PL/SQL procedure successfully completed. SQL> SQL> ed Wrote file afiedt.buf 1 declare 2 cursor c1 is select empno,ename from emp; 3 type emparray is table of c1%rowtype index by binary_integer; 4 rowarray emparray; 5 begin 6 open c1; 7 fetch c1 bulk collect into rowarray limit 100; 8 close c1; 9* end; SQL> / fetch c1 bulk collect into rowarray limit 100; * ERROR at line 7: ORA-06550: line 7, column 28: PLS-00597: expression 'ROWARRAY' in the INTO list is of wrong type ORA-06550: line 7, column 1: PL/SQL: SQL Statement ignored SQL>
9 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
PL/SQL procedure successfully completed. ops$tkyte@ORA9IR2> select * from v$version; BANNER -----------------------------------------------------------Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production PL/SQL Release 9.2.0.4.0 - Production CORE 9.2.0.3.0 Production TNS for Linux: Version 9.2.0.4.0 - Production NLSRTL Version 9.2.0.4.0 - Production
March 10, 2004 - 4pm Central time zone Reviewer: A reader Tom,
For index-by-table i have some doubts with the difference regarding index by binary_integer / index by varchar2(size_limit) I referred the docs which mention <doc> When you reference an element of an associative array that uses a VARCHAR2-based key, you can use other types, such as DATE or TIMESTAMP, as long as they can be converted to VARCHAR2 with the TO_CHAR function. </doc> I am still not clear as to why one would use index by varchar2.. can you please give me a example. Thanks.
OK March 11, 2004 - 9am Central time zone Reviewer: M.Srinivas from Hyderabad,AP,India Dear Tom, I would like to pass an array into a procedure and do some processing inside the procedure and return the processed output also as an array. For example: sql> create type nums_va as varying array(5) of number; and pass this array into a procedure like sql>create procedure p(array in out nocopy nums_va) as ... Is it possible to have a structure like this?Could you please help? Please do reply. Bye!
Table Record April 7, 2004 - 10pm Central time zone Reviewer: Tk from Orange Ca.
Tom I have this package nothing fancy. However, cannot figure out why I am getting. PLS-00382: expression is of wrong type Using ora: 8.1.7.4 Here it is. CREATE OR REPLACE package SRCH_PKG_1 is
10 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
TYPE t_stg_rec IS RECORD ( ID varchar2(20), SSN varchar2(9), FIRST_NAME varchar2(50), LAST_NAME varchar2(50) ); TYPE t_stg_tab IS TABLE OF t_stg_rec; i binary_integer := 1; function SEARCH_RESULT (IN_FNAME IN_LNAME IN_SSN IN_ID ) return t_stg_rec ; end ; / CREATE OR REPLACE package body SRCH_PKG as L_SSN L_FNAME L_LNAME BORROWER.SSN%TYPE ; BORROWER.FIRST_NAME%TYPE ; BORROWER.LAST_NAME%TYPE ; varchar2, varchar2, varchar2, in in in in varchar2, varchar2, varchar2, varchar2
function SEARCH_RESULT (IN_FNAME in IN_LNAME in IN_SSN in IN_ID in varchar2 ) return t_stg_rec is tstgrec t_stg_rec; tstgtab t_stg_tab; L_ID L_REC_CTR L_TREC_CTR is varchar2(50) number number := 0 := 0 ; ; ;
cursor cr (p_ID in varchar2, p_SSN in varchar2, p_FNAME in varchar2, p_LNAME in varchar2) select LA.APPL_ID, SSN, FIRST_NAME FNAME, LAST_NAME LNAME from CRT.LOAN_APPLICATION LA, CRT.BORROWER B where LA.LOAN_APPL_ID = B.LA_ID and SSN = p_SSN and FIRST_NAME like p_FNAME and LAST_NAME like p_LNAME ; BEGIN tstgtab := t_stg_tab(tstgrec); for tstgrec in cr (L_ID, L_SSN, L_FNAME, L_LNAME) loop tstgtab.extend; tstgtab(i) := tstgrec; --< ERROR!!!! PLS-00382: expression is of wrong type i := i + 1; -- some additional logic here end loop ; return tstgtab; END SEARCH_RESULT; END SRCH_PKG ;
11 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
"appear") looks like you might want to be coding: your_table := your_table_type(); open cr( ... ) loop fetch cr into your_record; exit when cr%notfound; your_table.extent; your_table(your_table.count) := your_record; end loop close cr;
just a comment here -- your naming convention would drive me utterly nuts. what is the type, what is the variable -- they look the same to me. I would seriously give thought to changing that practice.
Thank you it worked April 9, 2004 - 1pm Central time zone Reviewer: Tk from Orange, Ca In regards to naming convention could not agree with you more. I changed it.
Could you suggest or better publish naming standards that you use. What is better way of naming objects, types, and cursors, variable of above? I think this information will be very helpful for all levels of developers and DBAs. Kind of setting a baseline. In you book you do not really address this issue. However, I have seen a lot of poorly written code including mine. So if you could include to your preaching on use of bind variable also humane code practices that would make a world of good.
nested table question April 24, 2004 - 2pm Central time zone Reviewer: A reader In your expert one on one book - p 250 (WROX ed), you have given us the syntax of the nested storage clause. I understand your exp, imp trick but how did you manage to understand that syntax - esp. the part that allows you to specify the columns of nested table as well. "...store as emps_nt( empno not null, unique( empno), primary key ( nested_table_id, empno)...." I managed to figure out the syntax of giving oraganization index without specifying the columns (you still have to specify the primary key clause for the nested table) - hoewver, I am curious how did you figure out the above syntax (of specifying column details) in the first place? Also, the "unique" clause above - can that be applied to a normal create table? I know that you can specify PK creation as part of the table creation statement. Thanx!
12 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96594/toc.htm is an entire book on this stuff. unique, check, primary key, foreign key -- they can all be part of a CREATE TABLE
%ROWTYPE as IN parameter : mapping in jdbc June 17, 2004 - 7am Central time zone Bookmark | Bottom | Top Reviewer: Puneet Jain from India Hi I want to call a stored procedure having a %rowtype as input parameter from java code. I dont know how to set the parameter can u help me
to pass/return a "record", you would need to use a SQL TYPE create type foo as object (a int, b date, c varchar2(30) ) / then you can use jpub to automate a class that maps to that record.
July 15, 2004 - 1pm Central time zone Reviewer: Shalu Aggarwal from VA, USA Tom I have one question on nested tables: I have following table: SQL> desc vn_algorithm Name ----------------------------------------ALGORITHM_ID NAME SECURITY_TYPE
How can I do a distinct select on column 'security_type' which is a nested table of security types. I want something like this: Select distinct security_type from vn_algorithm where algorithm_id=1; Thanks! Shalu
July 15, 2004 - 2pm Central time zone Reviewer: Shalu Aggarwal from VA, USA
13 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
I made a mistake, the sql I want is: Select distinct security_type from vn_algorithm;
July 16, 2004 - 10am Central time zone Reviewer: Shalu Aggarwal from VA, USA Tom
It was really great to know this undocumented feature. And it helped figured my answer: select distinct b.* from vn_interpolation_algorithm table(a.SECURITY_TYPE) b;
a,
But I am stuck again in next qry, which is somethin like this: Select name From vn_interpolation_algorithm Where security_type='ABCD'; Meaning I want to select all the names where security type='ABCD'. Either I get ORA-00904: "B"."SECURITY_TYPE": invalid identifier OR ORA-01747: invalid user.table.column, table.column, or column specification when I do something like: Select name, b.* from vn_interpolation_algorithm a, table(a.SECURITY_TYPE) b where b.* = 'frmInt'; Pls advice what am i doing wrong.
but it is TRULY looking like you don't want a nested table -- you seem to be wanting to use the table as a table -- awkward at best with nested tables. that's one of the main reasons I don't use them to store data. in order to query that nested table -- you HAVE to do that unnesting -- you have to join, you do not have a table to query!!! I would rethink your data model, you are using an inappropriate construct for the questions you want to ask.
July 16, 2004 - 1pm Central time zone Reviewer: Shalu Aggarwal from VA, USA
Thanks for bringing this point, I didn't know that I am using a wrong contruct. It is a single column nested table. I cannot use a Varray because the no. of values is not fixed. Do I have any other options except splitting this table into two master detail tables ?
14 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
July 16, 2004 - 2pm Central time zone Reviewer: Shalu Aggarwal from VA, USA
That's why i implemented nested table because I knew that they are master detail. I also knew I will loose some flexibility but didn't know that wld restrict me to write a simple sql. Anyways, Is it a restriction of nested tables ? Can we not do that type of select from a nested table ? If we cannot, then what is the advantage of nested tables ? Pls help me clear my doubts. Thanks!
July 16, 2004 - 3pm Central time zone Reviewer: Shalu Aggarwal from VA, USA Tom I just figured out the qry w/o changing my construct: select a.name from vn_interpolation_algorithm a, table(a.SECURITY_TYPE) b Where b.column_value='ABCD';
I really need your comments on this. Would also like to know what is the reason you didn't suggest me this. Because nested tables generally limits flexibility or something else.
PK on Nested table August 2, 2004 - 12am Central time zone Reviewer: Branka from VA, USA
Is it posible to make PK on the table that has nested table, that would have one column form table and one column from nested table to be unique? I will use one of your exaples 1 create or replace type 2* bmyArrayType as table of bmyScalarType
15 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
SQL> / Type created. 1 create table x 2 ( id int , 3 array myArrayType 4 ) 5 nested table array store as X_Array_Data 6 ( 7 (PRIMARY KEY (nested_table_id, X)) 8 ORGANIZATION INDEX 9* ) 10 / Table created. I would like to have primary key on columns id (from table x) and X (from nested table X_Array_Data). If I can not make primary key, can I make index? If not, how can I stop user from inserting duplicate records, and that to be on database level?
Nested table PK August 2, 2004 - 12pm Central time zone Reviewer: Branka from VA, USA Is it posible to add PK on existing nested table? 1 create or replace type 2 bmyScalarType as object 3 ( x int, 4 y date 5* ) SQL> / Type created. 1 create or replace type 2* bmyArrayType as table of bmyScalarType SQL> / Type created. 1 create table bx 2 ( pk int primary key, 3 array myArrayType 4 ) 5* nested table array store as bX_Array_Data SQL> / Table created. I would like to have same result as with statement. Is it posible? 1 2 3 4 5 6 create table bx ( pk int primary key, array myArrayType ) nested table array store as bX_Array_Data (
16 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
since in order to be organization index, you must have specified the primary key -- so, can you add a primary key? YES. can you add a primary key and make it an IOT? NO.
nested table August 2, 2004 - 1pm Central time zone Reviewer: Branka from VA, USA What is difference between statements create 2 3 4 5 and create 2 3 4 5 table x ( pk int primary key, array myArrayType ) nested table store as X_Array_Data table x ( pk int primary key, array myArrayType ) nested table array store as X_Array_Data
Collection Variable Types January 3, 2005 - 4pm Central time zone Reviewer: Phil Garriss from US
This was very useful especially when you describe the difference between plsql arrays and non plsql types. However I do have a follow-up question. That is how is this better then inserting the
17 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
array into a global temporary table? Does this cover security concerns better or is it faster or does it take less space allocation? I am trying to determine if I should move in this direction. Thanks.
Collection Variable Types January 4, 2005 - 2pm Central time zone Reviewer: Phil Garriss from US
Ok. Thanks. It would be nice if Oracle would allow you to create the SQL object (the table) within PLSQL so that you could drop it later. That way you would not have to maintain various object and table types on the server. That means a lot more paper work and time checking things in and out. In other words our group was maintaining global temp tables but now we will have to maintain object and table types. However it is better then the 8i solution where the global temp table was the only alternative.
Collection Vs GTT January 5, 2005 - 2pm Central time zone Reviewer: Phil Garriss from US
Ok. I agree that it is nice to document the array specs. Perhaps someone will want to use it again. But the main question I have is this: if we have to create something on the server (ie. a type or a gtt) then is there a useful advantage to creating the table type over the gtt. For instance do the global temporary tables take up a certain amount of space on the server? Do the arrays get extended and deallocated by the procedure? Would an array work faster then using a global temporary table? If so then I do see the advantage of using this convention. Thanks.
Array Vs Global Temp Table January 6, 2005 - 10am Central time zone Reviewer: Phil Garriss from US There is a definite performance difference! I ran two similar reports. One into a global temporary table and passing the data to the report. The other into an array and passing that back through the reference cursor. The first seconds to run. The second report took 4 seconds. So it must be easier for
was inserting data was inserting data report took me 14 Oracle to extend and
18 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
insert data in an array then for it to insert and commit the transactions in a table.
Arrays Vs Global Temporary Table January 7, 2005 - 10am Central time zone Reviewer: Phil Garriss from US Can you give me a simple example. each. Thanks. Nothing fancy.
Collection Vs Global Temporary Table January 7, 2005 - 11am Central time zone Reviewer: Phil Garriss from US Thanks. That is exactly what I was wanting to know. Have a great weekend!
Inserted into Varray's and Extending them May 15, 2005 - 3pm Central time zone Reviewer: Roger from Montreal, Quebec Greetings Jedi Master Tom, Are these assertions right?
1) Varray's are immutable data types. So if you want to insert (or delete/update) something in a Varray after it has been initialized, you have to create a new varray and manually initialize it with the changes? If I am wrong, can you please give an example. I have checked out this example from Oracle's documentation which made me make the "Varray's are immutable" statement: CREATE PROCEDURE add_project ( dept_no IN NUMBER, new_project IN Project, position IN NUMBER) AS my_projects ProjectList; BEGIN SELECT projects INTO my_projects FROM department WHERE dept_no = dept_id FOR UPDATE OF projects; my_projects.EXTEND; -- make room for new project /* Move varray elements forward. */ FOR i IN REVERSE position..my_projects.LAST - 1 LOOP my_projects(i + 1) := my_projects(i); END LOOP; my_projects(position) := new_project; -- add new project UPDATE department SET projects = my_projects WHERE dept_no = dept_id; END add_project;
19 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
2) Extending a Varray is not useful because when you initialize the array, you specify the upper limit of the varray which cannot be changed. I have seen your examples (and the ones in Oracle documentation) that describe why/how to extend a nested table but not come across any code that extend's varrays. If extending varray's is necessary, can you please give an example. I searched your site thoroughly before posting these questions. If you have answered these questions before I am sorry to waste your time. Before posting I also made sure that I read the PLSQL Dev Guide Chapter on Collections and Records at: http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96624/05_colls.htm#20023 Thanks!
Varray's May 16, 2005 - 12pm Central time zone Reviewer: Roger from Montreal, Quebec Tom,
Thanks for your reply. A followup question for point (2). In your example, is it safe to assume that myArray is a nested table based on your previous posts on this discussion? i.e. <quote> @ORA920> create type myArray as table of varchar2(250) 2 / Type created. </quote> I had specifically asked if you you need to extend a VARRAY not a nested table. I understand that if you don't extend a nested table you will get the "ORA-06533: Subscript beyond count" error. But why would you need to extend a Varray if a Varray cannot increase in size once its been defined. Thanks alot. May the force be with you ;)
20 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
ops$tkyte@ORA9IR2> create or replace type myArray as varray(20) of number 2 / Type created. ops$tkyte@ORA9IR2> ops$tkyte@ORA9IR2> declare 2 l_data myArray := myArray(); 3 begin 4 l_data(1) := 0; 5 end; 6 / declare * ERROR at line 1: ORA-06533: Subscript beyond count ORA-06512: at line 4 a varray must allocate storage just as a nested table it has an absolute UPPER BOUND on the number of elements, but has none by default.
a related question May 16, 2005 - 1pm Central time zone Reviewer: Amiel from Tel-aviv
Dear tom, First of all I would like to say that this site is amazing. Here is my problem: In the application server we call a pl-function that does an insert. Because we cant pass it a pl-table, we have to call it n times for each line. I thought of building anonyms pl block that will construct the whole insert. E.g.: before Application server calls in a loop for a Pl that does an insert //pseudo c# syntax: for (int i =0; i <= 100; I++) Dbclass.InsertUsingPl(bind variable, etc); Problem: extra traversing from the application server to the db server. After Application server builds at once anonyms Pl block and then send it to the db //pseudo c# syntax: for (int i =0; i <= 100; I++) Building a large string that looks like that: Declare Type rec is record( t number(7), x number(2), y char(1)); Type Tbl is table of rec index by pls_integer; lTbl Tbl; Begin lTbl(1).t := 4890045; lTbl(1).x := 1; lTbl(1).y := '0'; lTbl(2).t := 4890045; lTbl(2).x := 2; lTbl(2).y := '1'; lTbl(3).t := 4890045; lTbl(3).x := 23; lTbl(3).y := 'Z'; ForAll i in 1 .. lTbl.Count Insert Into sample_table values lTbl (i); End; Problem: pollution of the shared pool. Each time we will sent it it will have a line in v$sqlarea. I did a test of my own (cant reproduce it here need an application server) Figure it out that the second method is slightly faster. Can you please give me your opinion about it? Amiel. p.s. a sample script: create table sample_table (t number (7), x number(2), y char(1)); and
21 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
create or replace function f_ins_sample_table(p_t in number, p_x in number, p_y in char, error out varchar2) return number is begin insert into sample_table (t, x, y) values (p_t, p_x, p_y); return 1; exception when others then error := sqlerrm; return - 1; end; OR Declare Type rec is record( t number(7), x number(2), y char(1)); Type Tbl is table of rec index by pls_integer; lTbl Tbl; Begin lTbl(1).t := 4890045; lTbl(1).x := 1; lTbl(1).y := '0'; lTbl(2).t := 4890045; lTbl(2).x := 2; lTbl(2).y := '1'; ForAll i in 1 .. lTbl.Count Insert Into sample_table values lTbl (i); End;
Question may be stupid but still an attemp May 16, 2005 - 3pm Central time zone Reviewer: Jupiter from Jupiter Hi Tom, Luv the site and ur answers. Question: The way one could say create table abc as select * from abc1@otherenv and a table with exact structure could be created similarly Is there a way where I could do the above for a package like create package abc as select package b from @otherenv Thanks a lot as always? -- So apart Oracle any plans for the long weekend? Salute to you answers
22 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Varrays May 16, 2005 - 6pm Central time zone Reviewer: Roger from Montreal Quebec Thanks Tom for explaining what the EXTEND method of a collection does.
BTW, on a side note, what is your opinion on Oracle certifications? OCP? OCM? Do you think they are valuable? Are you an OCM? And to digress even more, when are you watching the final episode of Stars Wars? I will not ask any more non-technical questions here. I know of your blog. Thanks.
May 17, 2005 - 1am Central time zone Reviewer: Amiel from tel aviv
first of all, thanks for the very fast response (wrote the response at night, got the answer in the morning) the reason that we cant use a pl/table come from the .net provider for oracle. Reading your answer, i thing of doing something like sending a big string to the sp, and use a static smart sql (the kind that you learned us to wrote) that will do insert as select straight to the table. what do you think about it (the insert as select idea)? regards, amiel
.NET and PL/SQL Associative Array May 17, 2005 - 8am Central time zone Reviewer: Mark A. Williams from Indianapolis, IN USA Hi Amiel,
Are you using the Oracle Data Provider for .NET? The Oracle provider does support the use of PL/SQL Associative Arrays (formerly known as "Index-By Tables") beginning with the 9.2.0.4.01 version of the provider. The Microsoft provider does not support this functionality so this might be another reason to use the Oracle provider if you are not already. If you point your browser to the Oracle Data Provider for .NET homepage on the Oracle Technology Network, then scroll to the bottom of the page you will find 2 sample chapters from my book. One of them (Chapter 5) illustrates using PL/SQL Associative Arrays for insert and select operations. The ODP.NET homepage can be found here: http://www.oracle.com/technology/tech/windows/odpnet/index.html Also, the ODP.NET forums on OTN can be found here: http://forums.oracle.com/forums/forum.jsp?forum=146 Hope that helps a bit, - Mark
May 17, 2005 - 10am Central time zone Reviewer: amiel from tel aviv
Mark - thank you very much, we are not using this provider, But the native microsoft provider so, i ask again, is doing something like sending a big string to the sp, and use a static smart sql (the kind that you learned us to wrote) that will Do insert as select straight to the table sound like a good idea?
23 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
May 17, 2005 - 11am Central time zone Reviewer: A reader I am glad Amiel (from tel aviv ) you are using this site :-) Asif.
May 18, 2005 - 5am Central time zone Reviewer: amiel from tel aviv
tom, thanks agin. could you please clarify about the gtt idea (we will stil have to insert data to it), i thing thet my aim is to minimize the traversing between the apllication server and the db server. i thougt of doing somthing like thet: create table sample_table (t number (7), x number(2), y char(1)); create or replace function f_ins_using_str(p_t in varchar2, error out varchar2) return number is begin --'1234567, 1,*#1234567, 2,*#1234567, 3,*#1234567, 4,*#1234567, 5,*' insert into sample_table (select * from (select To_Number(Trim(substr(Column_Value, 1, 7))) as t, To_Number(Trim(substr(Column_Value, 9, 3))) as x, substr(Column_Value, 13, 1) as y from (SELECT TRIM(Substr(p_t, Instr('#' || p_t || '#', '#', 1, Rownum), Instr('#' || p_t || '#', '#', 1, Rownum + 1) Instr('#' || p_t || '#', '#', 1, Rownum) - 1)) Column_Value FROM (select level from dual connect by level <= (Length(p_t) Length(REPLACE(p_t, '#', '')) + 1))))); return sql%rowcount;; exception when others then error := sqlerrm; return - 1; end; set serveroutput on declare ll number; err varchar2(400); begin ll := f_ins_using_str('1234567, 1,*#1234567, 2,*#1234567, 3,*#1234567, err); dbms_output.put_line(to_char(ll)) || 'record was written '); end; 5 record was written select * from sample_table T X Y 1234567 1 * 1234567 2 * 1234567 3 * 1234567 4 * 1234567 5 *
4,*#1234567,
5,*',
24 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
in order not to die without understanding the your answer, i must ask agin - how does the data move from the application server to the db server? as i wrote before, i can't send an array. what will i gain from doing insted of insert * n times right to my table, doing it as you say i will do insert to a gtt and then insert to my table. could you please be more clear on the gtt
tom and mark, thank you all very much. the it is not up to me to decied about the driver but i will pass the information on. p.s. 1: the string trick is very ugly but it was fun to write it... p.s. 2: what do you mean when you say array procecing in the client?
August 3, 2005 - 6am Central time zone Reviewer: Rajesh from India How to Handle ora-06550 error in PL/SQL block
25 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
ORA-06550 August 3, 2005 - 6am Central time zone Reviewer: Rajesh from India How to Handle ora-06550 error in PL/SQL block
May be a bug August 3, 2005 - 5pm Central time zone Reviewer: Marcio Portes from Brazil Tom, do you know if it is a bug? The code below runs against 8i but not over 9i/10g. create table x_tab ( cod number, nam varchar2(10) ); create or replace type xr_tab as object ( cod number, nam varchar2(10) ); / create or replace type xt_tab as table of xr_tab; / declare cursor c1 is select * from x_tab; t_tab xt_tab := xt_tab(); rec c1%rowtype; begin for rec in c1 loop t_tab.extend; t_tab(t_tab.last) := rec; end loop; end; / Regards,
Initialize Varray of records upon creation ... August 11, 2005 - 2pm Central time zone Reviewer: VKOUL from WA USA
Please go thru the following : *************************************************** DECLARE type flowType is record (priority number(1), fwdFlow number, revFlow number); TYPE flowtype_table IS VARRAY(3) OF flowtype; flow flowtype_table := flowtype_table(flowType(1,2,3), flowType(4,5,6), flowType(7,8,9)); BEGIN null; END; / *********************************************************** On executing the above PL/SQL block, I get this SQL> l 1 DECLARE 2 type flowType is record (priority number(1), fwdFlow number, revFlow number); 3 TYPE flowtype_table IS VARRAY(3) OF flowtype; 4 flow flowtype_table := flowtype_table(flowType(1,2,3), flowType(4,5,6), flowType(7,8,9)); 5 BEGIN 6 null; 7* END; SQL> SQL> SQL> / flow flowtype_table := flowtype_table(flowType(1,2,3), flowType(4,5,6), flowType(7,8,9)); * ERROR at line 4: ORA-06550: line 4, column 41: PLS-00222: no function with name 'FLOWTYPE' exists in this scope ORA-06550: line 4, column 8:
26 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
PL/SQL: Item ignored SQL> define DEFINE _DATE = "11-AUG-2005 11:29:43 AM" (CHAR) DEFINE _SQLPLUS_RELEASE = "1001000300" (CHAR) DEFINE _EDITOR = "Notepad" (CHAR) DEFINE _O_VERSION = "Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - Production With the Partitioning and Data Mining options" (CHAR) DEFINE _O_RELEASE = "1001000400" (CHAR) DEFINE _RC = "1" (CHAR) SQL> SQL> How Can I Initialize Varray of records upon creation in declaration section with some static values ? Thanks
Thanks Tom August 12, 2005 - 2pm Central time zone Reviewer: VKOUL from WA USA
Working with Collections and Bulk Collect November 8, 2005 - 4pm Central time zone Reviewer: Yuan from Newark, NJ USA
I am trying to do something with collections and bulk collect and not having much luck. illustrate what I'd like to do, I'll explain without using bulk. declare type lt is table of ltbl lt := lt(1, 2, begin -- STEP 1 for i in ltbl.first delete from testa if sql%rowcount > ltbl.delete(i); end if; end loop; -- STEP 2 for i in ltbl.first delete from testb if sql%rowcount > ltbl.delete(i); end if; end loop; end; Suffice it collection would I be don't have integer; 3); .. ltbl.last loop where id = ltbl(i); 0 then
To
to say that different logic is happening in steps 1 and 2, but if any elements in the are used in any given step, I want it to not be considered in any subsequent steps. Now able to accomplish this taking advantage of the performance gains of bulk collect? I a preference of using a varray or an index-by table.
I tried this: declare type lt is table of integer; ltblRemaining lt := lt(1, 2, 3); ltblDelete lt; begin forall i in ltblRemaining.first .. ltblRemaining.last delete from testa where id = ltblRemaining(i) returning i bulk collect into ltblDelete; end; But it's not letting me return i. If I return the element of i, how do I delete from ltblRemaining those that are also in ltblDelete?
27 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Fantastic! November 9, 2005 - 7am Central time zone Reviewer: Yuan from Newark, NJ USA Exactly what I need! Thanks!
index by binary_integer OR index by pls_integer November 11, 2005 - 4am Central time zone Bookmark | Bottom | Top Reviewer: Ravi Kumar from Gurgaon, India I have read somewhere that we should always use index by pls_integer NOT binary_interger. Is that right ? can you please explain. Thanks & Regards Ravi Kumar
I have setup second database from existing database. Then I have following error on one schema. (1). Package: CREATE OR REPLACE PACKAGE FONDSRPT.query_idx_tst AUTHID DEFINER AS TYPE idx_his_wgh_1_t IS RECORD ( idx_cus VARCHAR (10), idx_dat_ref DATE, idx_dat_ref_val NUMBER, idx_from DATE, idx_from_factor NUMBER, idx_nam VARCHAR (10), fx_cur VARCHAR (3), wgh NUMBER, asof DATE, val NUMBER, fx_rate NUMBER ); TYPE idx_his_wgh_1_ref_t IS REF CURSOR RETURN idx_his_wgh_1_t; TYPE idx_his_yld_t IS RECORD ( idx_cus VARCHAR2 (10 BYTE), idx_dat_ref DATE, idx_dat_ref_val NUMBER, idx_from DATE, idx_from_factor NUMBER, idx_nam VARCHAR2 (10 BYTE), asof DATE, yield NUMBER ); TYPE idx_his_yld_tab_t IS TABLE OF idx_his_yld_t; ....
28 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
FUNCTION idx_his_yld (c_idx_his idx_his_wgh_1_ref_t) RETURN idx_his_yld_tab_t PIPELINED; END; / CREATE OR REPLACE PACKAGE BODY FONDSRPT.query_idx_tst IS FUNCTION idx_his_yld (c_idx_his idx_his_wgh_1_ref_t) RETURN idx_his_yld_tab_t PIPELINED IS in_rec_d0 idx_his_wgh_1_t; in_rec_d1 idx_his_wgh_1_t; in_rec_tbl idx_his_wgh_1_tab_t := idx_his_wgh_1_tab_t (); in_cmp_tbl idx_his_wgh_1_tab_t := NULL; out_rec idx_his_yld_t; i1 INTEGER; i2 INTEGER; n_weight NUMBER; v_idx_cus VARCHAR (10); d_idx_from DATE; d_asof DATE; n_yield_day NUMBER; n_yield_tot NUMBER; BEGIN in_rec_tbl.EXTEND (10); i1 := in_rec_tbl.FIRST; n_weight := 0; v_idx_cus := NULL; d_idx_from := NULL; d_asof := NULL; n_yield_tot := 1; LOOP FETCH c_idx_his INTO in_rec_tbl (i1); EXIT WHEN c_idx_his%NOTFOUND; IF (NOT (v_idx_cus IS NULL)) AND (v_idx_cus = in_rec_tbl (i1).idx_cus) AND (NOT (d_idx_from IS NULL)) AND (d_idx_from = in_rec_tbl (i1).idx_from) AND (NOT (d_asof) IS NULL) AND (d_asof = in_rec_tbl (i1).asof) THEN v_idx_cus := in_rec_tbl (i1).idx_cus; d_idx_from := in_rec_tbl (i1).idx_from; d_asof := in_rec_tbl (i1).asof; n_weight := n_weight + in_rec_tbl (i1).wgh; ELSE --check for new index or initial index IF (v_idx_cus IS NULL) OR (v_idx_cus <> in_rec_tbl (i1).idx_cus) THEN n_yield_tot := 1; in_cmp_tbl := NULL; --new index has been detected --ouput the initial yield of one out_rec.idx_cus := in_rec_tbl (in_rec_tbl.FIRST).idx_cus; out_rec.idx_dat_ref := in_rec_tbl (in_rec_tbl.FIRST).idx_dat_ref; out_rec.idx_dat_ref_val := in_rec_tbl (in_rec_tbl.FIRST).idx_dat_ref_val; out_rec.idx_from := in_rec_tbl (in_rec_tbl.FIRST).idx_from; out_rec.idx_from_factor := in_rec_tbl (in_rec_tbl.FIRST).idx_from_factor; out_rec.idx_nam := in_rec_tbl (in_rec_tbl.FIRST).idx_nam; out_rec.asof := in_rec_tbl (in_rec_tbl.FIRST).asof; out_rec.yield := n_yield_tot;-- * (out_rec.idx_from_factor); PIPE ROW (out_rec); END IF; --new index-section in benchmark detected --yield to be continued IF d_idx_from IS NULL OR (d_idx_from <> in_rec_tbl (i1).idx_from) THEN --n_yield_tot := 1; in_cmp_tbl := NULL; END IF; v_idx_cus := in_rec_tbl (i1).idx_cus; d_idx_from := in_rec_tbl (i1).idx_from; d_asof := in_rec_tbl (i1).asof; n_weight := in_rec_tbl (i1).wgh;
--discard
29 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
in_rec_tbl (in_rec_tbl.FIRST) := in_rec_tbl (i1); i1 := in_rec_tbl.FIRST; END IF; --out_rec.yield := n_weight; PIPE ROW (out_rec); IF (n_weight = 1) THEN -out_rec.yield := 100; -PIPE ROW (out_rec); IF in_cmp_tbl IS NULL THEN in_cmp_tbl := in_rec_tbl; -out_rec.yield := 101; -PIPE ROW (out_rec); ELSE -out_rec.yield := 102; -PIPE ROW (out_rec); n_yield_day := 0; FOR i2 IN in_rec_tbl.FIRST .. i1 LOOP IF (in_cmp_tbl (i2).val) <> 0 THEN n_yield_day := n_yield_day + ( ( in_rec_tbl (i2).val / NVL (in_rec_tbl (i2).fx_rate, 1) ) / ( in_cmp_tbl (i2).val / NVL (in_cmp_tbl (i2).fx_rate, 1) ) * in_rec_tbl (i2).wgh ); END IF; END LOOP; in_cmp_tbl := in_rec_tbl; n_yield_tot := n_yield_tot * n_yield_day; out_rec.idx_cus := in_rec_tbl (in_rec_tbl.FIRST).idx_cus; out_rec.idx_dat_ref := in_rec_tbl (in_rec_tbl.FIRST).idx_dat_ref; out_rec.idx_dat_ref_val := in_rec_tbl (in_rec_tbl.FIRST).idx_dat_ref_val; out_rec.idx_from := in_rec_tbl (in_rec_tbl.FIRST).idx_from; out_rec.idx_from_factor := in_rec_tbl (in_rec_tbl.FIRST).idx_from_factor; out_rec.idx_nam := in_rec_tbl (in_rec_tbl.FIRST).idx_nam; out_rec.asof := in_rec_tbl (in_rec_tbl.FIRST).asof; out_rec.yield := n_yield_tot;-- * (out_rec.idx_from_factor); PIPE ROW (out_rec); END IF; i1 := in_rec_tbl.FIRST; n_weight := 0; --v_idx_cus := NULL; --d_idx_from := NULL; --d_asof := NULL; ELSE i1 := i1 + 1; END IF; END LOOP; CLOSE c_idx_his; RETURN; END; ... END; / (2). The function : idx_his_yld in this package is calling from following view. CREATE OR REPLACE FORCE VIEW FONDSRPT.V_IDX_CUS_YIELD (IDX_CUS, IDX_DAT_REF, IDX_DAT_REF_VAL, IDX_FROM, IDX_FROM_FACTOR, IDX_NAM, ASOF, YIELD) AS SELECT distinct idx_cus, idx_dat_ref, idx_dat_ref_val, idx_from, idx_from_factor, idx_nam, asof, yield FROM TABLE (fondsrpt.query_idx_tst.idx_his_yld (CURSOR (SELECT t3.* FROM v_idx_his_yld t3,
/* Package */
30 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
tidxday.idx_cus, tidxday.idx_from,
MAX (tidxday.asof) AS
tfundstatic.per_idx_cus, MAX (tfundvalue.fp_pre_datum ) AS fp_pre_dat_ubound, TRUNC (tfundvalue.fp_pre_datum, 'MM' ) fp_pre_month FROM v_fun_his_per tfundvalue, fund tfundstatic WHERE tfundvalue.dd_fon_nr = tfundstatic.fond_id GROUP BY tfundstatic.per_idx_cus,TRUNC(tfundvalue.fp_pre_datum,'MM')) tfundmonth, (SELECT idx_cus, idx_from, asof,SUM (wgh) wgh_sum,TRUNC (asof,'MM') asof_month FROM v_idx_his_yld GROUP BY idx_cus, idx_from, asof) tidxday WHERE tidxday.idx_cus = tfundmonth.per_idx_cus AND tidxday.asof_month = tfundmonth.fp_pre_month AND tidxday.wgh_sum = 1 AND tidxday.asof < tfundmonth.fp_pre_dat_ubound GROUP BY tidxday.idx_cus, tidxday.idx_from, tidxday.asof_month UNION SELECT tidxday.idx_cus, tidxday.idx_from,MAX (tidxday.asof) AS asof,'SOF' AS valtype FROM (SELECT tfundstatic.per_idx_cus, MIN (tfundvalue.fp_pre_datum ) AS fp_pre_dat_ubound FROM v_fun_his_per tfundvalue, fund tfundstatic WHERE tfundvalue.dd_fon_nr = tfundstatic.fond_id GROUP BY tfundstatic.per_idx_cus) tfundstart, (SELECT idx_cus,MIN (idx_from) AS idx_from,asof, SUM (wgh) wgh_sum FROM v_idx_his_yld GROUP BY idx_cus, asof) tidxday WHERE tidxday.idx_cus = tfundstart.per_idx_cus AND tidxday.wgh_sum = 1 AND tidxday.asof < tfundstart.fp_pre_dat_ubound GROUP BY tidxday.idx_cus, tidxday.idx_from) t4 WHERE t3.idx_cus = t4.idx_cus AND t3.idx_from = t4.idx_from AND t3.asof = t4.asof ) ) ) --439 |;; My problem is This view is working fine in original database. But new database it is not working. it gives following error: ERROR at line 4: ORA-06533: Subscript beyond count ORA-06512: at "FONDSRPT.QUERY_IDX_TST", line 297 Line 297 in Package as below in above function. FETCH c_idx_his INTO in_rec_tbl (i1); The database infrastructure is exactly same as original database. Could you please tell what I have missed to get above error? Thank you
FROM (SELECT
31 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
BEGIN in_rec_tbl.EXTEND (10); i1 := in_rec_tbl.FIRST; your array permits only 1..10 as subscripts as you have coded, i1 must have a value outside of this range somehow. try using dbms_output to print out values of variables as you go through and see what you see...
Bulk collect in index by varchar2 pl/sql tables June 21, 2006 - 12pm Central time zone Bookmark | Bottom | Top Reviewer: Ashutosh Upadhyay from Santiago, Chile Tom, I'm not able to populate index by varchar2 pl/sql table using bulk collect. Currently I'm doing it using a cursor loop. Please tell if it is possible. I'm using Oracle9i db. Program: DECLARE TYPE recratepref IS RECORD ( rate_type cltms_product.rate_type%TYPE, rate_code_pref cltms_product.rate_code_pref%TYPE ); TYPE tblratepref IS TABLE OF recratepref INDEX BY cltms_product.product_code%TYPE; v_rate_pref tblratepref; cnt NUMBER; t_rate_type cltms_product.rate_type%TYPE; t_rate_code_pref cltms_product.rate_code_pref%TYPE; BEGIN FOR m IN (SELECT product_code, rate_type, rate_code_pref FROM cltms_product) LOOP v_rate_pref (m.product_code).rate_type := m.rate_type; v_rate_pref (m.product_code).rate_code_pref := m.rate_code_pref; END LOOP; END;
Is that an appropriate way? September 13, 2006 - 1pm Central time zone Reviewer: Khurram Siddiqui from Paksitan ,KHI hi tom, please correct me someone asked at otn ....
Please try to get output from Pl/Sql block with Message . you will get the error.please insert more than one values and then test. here is his code 1 declare 2 cursor c1 is 3 select * from borrower; 4 begin 5 for w in c1 loop 6 message('contact name: '||w.name); 7 for i in 1..w.tools.count loop 8 message(w.tools(i)); 9 end loop; 10 end loop; 11* end; SQL> / message(w.tools(i)); * ERROR at line 8: ORA-06550: line 8, column 1:
32 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
PLS-00306: wrong number or types of arguments in call to 'MESSAGE' ORA-06550: line 8, column 1: PL/SQL: Statement ignored I replied DBMS_OUTPUT.PUT_LINE is an overloaded procedure which accept the static type e.g varchar,number. Why do you want to print anyway if you want to get the value from outside then use reference cursor (not sure cause not tested yet). then i tried in this way SQL> DROP TABLE borrower 2 / Table dropped. SQL> DROP TYPE tools_va 2 / Type dropped. SQL> DROP TYPE tool_ty 2 / Type dropped. SQL> CREATE TYPE tool_ty AS OBJECT 2 / Type created. SQL> CREATE OR REPLACE TYPE tools_va as VARRAY(10) OF 2 / Type created. SQL> CREATE TABLE borrower 2 (name VARCHAR2(25), 3 tools TOOLS_VA) 4 / Table created. SQL> INSERT INTO borrower VALUES ('A',tools_va(tool_ty('a'))) 2 / 1 row created. SQL> INSERT INTO borrower VALUES ('B',tools_va(tool_ty('b'))) 2 / 1 row created. SQL> INSERT INTO borrower VALUES ('C',tools_va(tool_ty('c'))) 2 / 1 row created. SQL> CREATE OR REPLACE PACKAGE mypackage AS 2 TYPE c1 IS REF CURSOR; 3 FUNCTION get_data RETURN c1; 4 END; 5 / Package created. SQL> 2 3 4 5 6 7 8 9 CREATE OR REPLACE PACKAGE BODY mypackage AS FUNCTION get_data RETURN c1 IS c c1; BEGIN OPEN c FOR SELECT p.tools FROM borrower p; RETURN c; END; END; / tool_ty (toolname varchar2(25))
Package body created. SQL> SQL> 2 3 4 SQL> VAR res REFCURSOR; BEGIN :res:=mypackage.get_data; END; . /
33 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
PL/SQL procedure successfully completed. SQL> PRINT res TOOLS(TOOLNAME) -------------------------------------------------------------------------------TOOLS_VA(TOOL_TY('a')) TOOLS_VA(TOOL_TY('b')) TOOLS_VA(TOOL_TY('c')) i wana ask is my assumption correct or there is more reliable and simple way to achive the op's requirment. Khurram
what message is September 13, 2006 - 3pm Central time zone Reviewer: Khurram Siddiqui from Pakistan,KHI
Sorry tom "message" was at form builder side sp actually it is equvalent to DBMS_OUTPUT.PUT_LINE here i paste the code again 1 declare 2 cursor c1 is 3 select * from borrower; 4 b tools_va; 5 begin 6 for w in c1 loop 7 dbms_output.put_line('contact name: '||w.name); 8 for i in 1..w.tools.count loop 9 b:=tools_va(tool_ty((i))); 10 dbms_output.put_line(b); 11 end loop; 12 end loop; 13* end; SQL> / dbms_output.put_line(b); * ERROR at line 10: ORA-06550: line 10, column 5: PLS-00306: wrong number or types of arguments in call to 'PUT_LINE' ORA-06550: line 10, column 5: PL/SQL: Statement ignored i made assumption that DBMS_OUTPUT.PUT_LINE is an overloaded procedure which accept the static type e.g varchar,number.So i made assumption "Why do you want to print anyway if you want to get the value from outside then use reference cursor." SQL> DROP TABLE borrower 2 / Table dropped. SQL> DROP TYPE tools_va 2 / Type dropped. SQL> DROP TYPE tool_ty 2 / Type dropped. SQL> CREATE TYPE tool_ty AS OBJECT 2 / Type created. SQL> CREATE OR REPLACE TYPE tools_va as VARRAY(10) OF tool_ty (toolname varchar2(25))
34 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Type created. SQL> CREATE TABLE borrower 2 (name VARCHAR2(25), 3 tools TOOLS_VA) 4 / Table created. SQL> INSERT INTO borrower VALUES ('A',tools_va(tool_ty('a'))) 2 / 1 row created. SQL> INSERT INTO borrower VALUES ('B',tools_va(tool_ty('b'))) 2 / 1 row created. SQL> INSERT INTO borrower VALUES ('C',tools_va(tool_ty('c'))) 2 / 1 row created. SQL> CREATE OR REPLACE PACKAGE mypackage AS 2 TYPE c1 IS REF CURSOR; 3 FUNCTION get_data RETURN c1; 4 END; 5 / Package created. SQL> 2 3 4 5 6 7 8 9 CREATE OR REPLACE PACKAGE BODY mypackage AS FUNCTION get_data RETURN c1 IS c c1; BEGIN OPEN c FOR SELECT p.tools FROM borrower p; RETURN c; END; END; /
Package body created. SQL> SQL> 2 3 4 SQL> VAR res REFCURSOR; BEGIN :res:=mypackage.get_data; END; . /
PL/SQL procedure successfully completed. SQL> PRINT res TOOLS(TOOLNAME) -------------------------------------------------------------------------------TOOLS_VA(TOOL_TY('a')) TOOLS_VA(TOOL_TY('b')) TOOLS_VA(TOOL_TY('c')) So is my assumption is correct or there is some more reliable way?? i hope you got what i wana make sure from you. sorry to bothering you again by repasting the code. Thanx a lot for yours prompt response SQL> SELECT banner FROM v$version; BANNER ---------------------------------------------------------------Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production PL/SQL Release 9.2.0.1.0 - Production CORE 9.2.0.1.0 Production TNS for 32-bit Windows: Version 9.2.0.1.0 - Production NLSRTL Version 9.2.0.1.0 - Production Khurram
35 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
Bulk Collect into Table of Varray January 10, 2007 - 12pm Central time zone Reviewer: Gwen from Virginia US Tom, I can bulk collect into three separate tables of, say, VARCHAR2(30)s. DECLARE TYPE varlist_typ IS TABLE OF VARCHAR2(30); list1_tab varlist_typ; list2_tab varlist_typ; list3_tab varlist_typ; TYPE ref_cur_typ IS REF CURSOR; ref_cur ref_cur_typ; BEGIN OPEN ref_cur FOR 'SELECT field_1, field_2, field_3 FROM my_table WHERE id = 1000'; FETCH ref_cur BULK COLLECT INTO list1_tab, list2_tab, list3_tab; CLOSE ref_cur; dbms_output.put_line (list1_tab(1) || ' ' || list2_tab(1) || ' ' || list3_tab(1)); dbms_output.put_line (list1_tab(2) || ' ' || list2_tab(2) || ' ' || list3_tab(2)); END; I can loop through the records in each table. Now I also need to loop though all the fields as a VARRAY. So I'd like to declare something like this: DECLARE TYPE varray_typ IS VARRAY(3) of VARCHAR2(30); TYPE varray_tab_typ IS TABLE OF varray_typ; varray_tab varray_tab_typ; TYPE ref_cur_typ IS REF CURSOR; ref_cur ref_cur_typ; BEGIN OPEN ref_cur FOR 'SELECT field_1, field_2, field_3 FROM my_table WHERE id = 1000'; FETCH ref_cur BULK COLLECT INTO varray_tab???, varray_tab???, varray_tab???; CLOSE ref_cur; END;
How can I refer to each element in the varray for the bulk collect? Do I need to initialize the varray and how is this done? I have simplified this down - what I really need is a varray with 300 elements. Individually named items won't work for later processing. Also, the OPEN and FETCH will be using dynamic strings. I believe I can do the FETCH with EXECUTE IMMEDIATE as long as my variables are globals. Thanks for your help! Gwen GTT vs. PL/SQL Tables February 2, 2007 - 7pm Central time zone Reviewer: Jhon from USA Hi Tom, Sorry for the intrusion in this thread since I could not post a new question to you. I kinda hoping you will be able to help me to find some concrete samples showing the effectiveness of GTT against P/SQL tables (bulk collect) in a process or vice-versa. In short, I like to know which one is faster and will have less SGA usage. Bookmark | Bottom | Top
36 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
The process requires data gathering from huge tables (with of course some conditions), then manipulate the data. The final results will then be saved to a different physical table. BTW, I'm using Oracle DB v9.2.0.4. Thanks is advance
in short "it depends on what the heck you are doing" do you need an array in your procedural code? plsql table type do you need to use a scratch table for intermediate processing? global temporary table. Error February 23, 2007 - 2pm Central time zone Reviewer: Naga from US Hi Tom, Sorry for posting my question here . But i am really need ur help. I have to create a procedure that returns a nested table . and use that nested table in ProC. Attached is my code ...Please me I am not sure What is going wrong? the procedure is created? But when i use select * from table (cast(positionspkg_getpositions() as position_table_type)) its throwing me an error... SET SERVEROUTPUT ON; CREATE OR REPLACE PACKAGE POSITIONS_PKG IS TYPE position_rec_type IS RECORD ( AccountKey VARCHAR2(16), SecurityKey VARCHAR2(16), AccountType NUMBER(3), Symbol VARCHAR2(16), ChargeScheduleKey VARCHAR2(16), SecurityDescription VARCHAR2(100), UnderlyingSecurityKey VARCHAR2(16) ); TYPE position_table_type IS TABLE OF position_rec_type; Bookmark | Bottom | Top
37 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
END; / COMMIT; SHOW ERRORS; CREATE OR REPLACE PACKAGE BODY POSITIONS_PKG AS function getPositions return position_table_type is cursor c_positions IS SELECT pos.accountkey, pos.securitykey, pos.accounttype, sec.symbol, cust.chargeschedulekey, sec.securitydescription, sec.underlyingsecuritykey FROM positions pos INNER JOIN securities sec ON ( pos.securitykey = sec.securitykey ) LEFT JOIN positionstrategies posstrat ON (pos.accountkey =posstrat.accountkey) and (pos.accounttype = posstrat.accounttype) INNER JOIN customers cust ON (pos.accountkey = cust.customerkey ) LEFT JOIN securitymarginmanagement secmar ON (pos.securitykey = secmar.securitykey) LEFT JOIN positionmarginmanagement posmar ON (pos.accountkey = posmar.accountkey) LEFT JOIN securitiesfixedincome secfix ON (pos.securitykey = secfix.securitykey) FOR v_data_position in c_positions loop begin positiontable.extend; --positionrec.AccountKey := v_data_position.accountKey; --positionrec.Symbol := v_data_position.symbol; --positiontable.extend; positiontable(n_pos) := positionrec; n_pos := n_pos + 1; end ; end loop; /* open c_positions; loop fetch c_positions into positionrec; exit when c_positions%NOTFOUND; positiontable.extend; for i in 1..positiontable.COUNT loop positiontable(i) := positionrec; end loop; end loop; close c_positions; */ return positiontable; END; END; / COMMIT; SHOW ERRORS;
select * from table(cast(positions_pkg.getpositions() as position_table_type)) 2/ select * from table(cast(positions_pkg.getpositions() as position_table_type)) * ERROR at line 1: ORA-00902: invalid datatype
38 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
create or replace type position_rec_type as object ( AccountKey VARCHAR2(16), SecurityKey VARCHAR2(16), AccountType NUMBER(3), Symbol VARCHAR2(16), ChargeScheduleKey VARCHAR2(16), SecurityDescription VARCHAR2(100), UnderlyingSecurityKey VARCHAR2(16) ) / create or replace type position_table_type IS TABLE OF position_rec_type / Unnesting Null Objects March 16, 2007 - 8am Central time zone Reviewer: Brett from Richmond VA Bookmark | Bottom | Top
I hope that I'm missing something very basic here. I'm trying to unnest collections that may be null in 9.2.0.7. Here's a simplistic example: --Type creations CREATE TYPE test_type AS OBJECT (test_type1 VARCHAR2(30), test_type2 VARCHAR2(30)); / CREATE TYPE test_array AS TABLE OF test_type; / --Table creations CREATE TABLE test (test1 VARCHAR2(30), test2 VARCHAR2(30), test3 test_array) NESTED TABLE test3 store AS test3_tab; --Test data INSERT INTO test (test1,test2) VALUES (1,1); INSERT INTO test (test1,test2,test3) VALUES (2,2,test_array(test_type('A','A'),test_type('B','B'))); Now, once I start pulling the data out, I see that I have 2 rows in the parent table: SELECT * FROM test; But, when I try to unnest the collections, I only get data for one of the parent rows because one of the has no data in the nested table: SELECT a.test1, a.test2, b.test_type1, b.test_type2 FROM test a, TABLE (a.test3) b; I can get the parent row back by creating a null object in the nested table, but I am still missing the parent row 1: INSERT INTO test (test1,test2,test3) VALUES (3,3,test_array(test_type(NULL,NULL))); SELECT a.test1, a.test2, b.test_type1, b.test_type2 FROM test a, TABLE (a.test3) b; I can update row 1 so that it has a null object in the nested table and then retrieve it: UPDATE test SET test3 = test_array(test_type(NULL,NULL)) WHERE test1 = 1; SELECT a.test1, a.test2, b.test_type1, b.test_type2 FROM test a, TABLE (a.test3) b; And now finally, my question: Is there some sort of outer join syntax for unnesting collections or do I simply have to ensure that an object exists in the nested table for every row in the parent table? I've looked through documentation and can't seem to find anything. Answering my own question March 16, 2007 - 9am Central time zone Reviewer: Brett from Richmond VA I knew that once I posted the question, I would stumble upon the results: SELECT a.test1, a.test2, b.test_type1, b.test_type2 FROM test a, TABLE (a.test3)(+) b; Bookmark | Bottom | Top
39 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
ops$tkyte%ORA10GR2> SELECT a.test1, a.test2, b.test_type1, b.test_type2 2 FROM test a, TABLE (nvl(a.test3,test_array(test_type(null,null)))) b 3 / TEST1 -------1 2 2 TEST2 -------1 2 2 TEST_TYPE1 TEST_TYPE2 ------------ -----------A B A B
is "yet another way" Real World Use of Nested Tables ? OR might be not April 7, 2007 - 1pm Central time zone Bookmark | Bottom | Top Reviewer: Rakesh from India Hi , I wanted to ask this very sticky(to me) question.I read that real world use of nested tables are scarce,wanted to confirm if this is a veritable nested table scenarion.My case is if there are different departments,with each department offering multiple subjects,each independent of the other.i.e both history and sociology department may offer one subject of common interest.Must i use nested tables or go for parent-child table relationship. Please and Kindly Clarify
Hi. PL/SQL Tables with .net September 18, 2007 - 11am Central time zone Reviewer: Mohanraj K. from INDIA Hello Sir, I am new to this forum.
I searched through all odp.net forum, and some sample chapters, but unable to clearly use it. Can i get any help on How to PASS PL/SQL tables ( or some table like information )into stored procedures from .NET (ODP.NET) and process that table( and referencing its elements) of information in PL/SQL. I read about Associative Arrays samples, It seems like some what oldage, can we access the type table of (element type) in the .net itself. Please give me clear example on passing parameters of Associative Arrays in stored procedures from .NET Thanks in Advance.
Reverse Engineering November 21, 2007 - 3am Central time zone Reviewer: A developer from UK Tom,
We have talked a lot about how to populate various data structures. However, in my case Java code will be used to populate a RECORD type.( That's nice, since I don't have to worry about it at all). Now, I have to apply some logic on this RECORD type and subsequently update a couple of tables. I am not sure what the best way to go about this is. Please guide me.
Hi Tom, I have an extremely basic question - I am not sure what mistake I'm making in the code below, or if what I am attempting is actually possible:
40 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
SQL> create or replace type t_object_type as object (enterprise varchar2(40), qtysum number); 2/ Type created SQL> create or replace type t_object_table as table of t_object_type; 2/ Type created create or replace function f_temp return number is rec_variable t_object_table; begin execute immediate 'select enterprise, sum(quantity) qtysum from orders group by enterprise' bulk collect into rec_variable ; return 0; end f_temp; On executing this, I get the following error: ORA-00932: inconsistent datatypes: expected - got Using a 'record' in place of an object works. Meaning, 'create type t_record_type is record (enterprise varchar2(40), qtysum number) You might question the use of dynamic sql here. Actually in the actual application, the query would be built dynamically. And, the object types for the query would be created in the dictionary automatically. I have provided this simple example only to keep the test case 'short, concise and complete'! Thanks and Regards, Vinay Chandrakant
you need to select your scalar object - into a table of objects! Table of objects December 4, 2007 - 8am Central time zone Reviewer: Vinay Chandrakant from Bangalore, India Bookmark | Bottom | Top
Hi Tom, Thanks a lot - though the question was really silly after all - I guess I must've been too tired and wasn't even looking at my own code properly :-( Thanks!! Vinay
Transient object types December 4, 2007 - 8am Central time zone Reviewer: Vinay Chandrakant from Bangalore, India
Hi Tom, I am not sure if this would be considered a 'followup' - it deals with objects and collections though - so I thought this is the right place. Please let me know if this was the wrong place to post this. I have transient types created in the dictionary to match the structure of the resultset of a dynamically generated query. But I can't seem to be able to use them like this: select "SYSTPQHCzGF7IbMngRAADunUR+w=="(enterprise,quantity) ... into my_object_table What I get is: ORA-22833: Must cast a transient type to a persistent type Is there a 'workaround' or some way I can use it this way? What I need is: I have a certain dynamically generated query and I need to collect the resultset into a collection for subsequent processing. The object type is available in the dictionary for me to use (as a transient type). Short of using dynamic PL/SQL to create an anonymous block that declares a object type to match the structure of my resultset, is there any way I can use the available structure of the transient type? Thanks and Regards, Vinay Chandrakant
41 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
compare collections column names December 26, 2007 - 6am Central time zone Reviewer: Ram Joshi from INDIA Hi Tom, I'm on Oracle 9i and I want to load data from a work table to the base table. There are couple of things that im unclered with..
1.) Im using DBMS_SQL package to read the data from Work table along with column names using DBMS_SQL.DESCRIBE_COLUMNS . 2.) The column names in the second (base) table is EXACTLY identical to the work table ,However with few extra columns as well as the order of columns is also not the same. 3.) I have declared two TYPES based on the both tables and I just need to navigate (loop) through the record columns compare it with the first record column and if the column names are similar...Add the column value in the record variable column name. But Im unable to do so as i cannot get the column names dynamically in record type variable as well as compare it also. Can u please help me on this? Just to illustrate : TAble 1(Work TAble) : EMP (Ename VARCHAR2(200) SAL VARCHAR2(200) DEPT VARCHAR2(200) HIREDATE VARCHAR2(200) ) TAble2 (Base TAble) : EMP_BASE (Ename VARCHAR2(200) HIREDATE DATE DEPT VARCHAR2(200) SAL Number ) (Please note ORDER of columns is NOT same in EMP_BASE table as well as the DATA TYPE !!!) TYPE emp_tab emp_rec TYPE emp_base_tab emp_base_rec IS TABLE OF EMP%rowtype; emp_tab := emp_tab(); IS TABLE OF EMP_BASE%rowtype; emp_base_tab := emp_base_tab();
I want to loop through ALL the columns of EMP table one by one,Compare it with the column name of EMP_BASE table and if it is the same then I need to put the value against that column using the record types. So could you please guide me as to how do i navigate through the record type variable and to get the column name also? I hope you got my problem.... Regards Ram.
sounds a lot like you just want to MERGE - eg: there should be no code written here at all, a single SQL DML statement is what you were looking for. Still.... December 27, 2007 - 6am Central time zone Reviewer: Ram Joshi from INDIA Hi Tom, First of all I appollogize for the "U" thing.I'm really SORRY for that... So does this mean that We cannot get the column names of the record ? I mean if we have two record variables rec_var1 and rec_var2 and say ORDER_KEY is the FIRST column in rec_var1 and say FIFTH column in rec_var2 ,So when I'm looping through EACH column of rec_var1 and only when the corresponding column in rec_var2 is matched ,I want to assign that value to this column of rec_var2. So my question is how do I come to know if the FIFTH column is the ORDER_KEY column in rec_var2? Bookmark | Bottom | Top
42 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
How do I get the colun name of the record? Cant we get this info dynamically ? I mean is this really NOT POSSIBLE in PL/SQL?? Thanks in advance once again, Ram.
I have a procedure that modifies the password of an Oracle user with a random generated password. But now I have a new requirement: The new password must be encrypted with a list of n public Keys (PuKs of RSA) sent by client with n=1..few dozens, and all resulting encrypted strings must be sent to the end client. These are my ideas to achieve it: 1) Receive the Puks list as a parameter of the procedure, being : A- an associative array where the index will be the PuK string (128 bytes), and the content will be the encrypted password for that PuK (OUT). type t_puk_encrypted_list is table of varchar2(256) index by varchar2(256); PROCEDURE crypt_pass (p_password varchar2(15), p_puk_encrypted_list IN OUT)
43 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
B- an associative array with an integer index, and other parameter for returning the encrypted password list, being the index the reference between the two parameters, I mean: p_encrypted_list(i) will be the encrypted password with the p_puk_list(i) type t_puk_list is table of varchar2(256); type t_encrypted_list is table of varchar2(256); PROCEDURE crypt_pass (p_password varchar2(120), p_puk_list IN, p_encrypted_list OUT) 2) I will need using operative system tools to encrypt the password with RSA, since dbms_crypto doesn't support this algorithm. For each element of the collection, call to operative system shell to generate the encrypted password and load the array with it. I have read that the accesses to Operative System from database might be done using dbms_scheduler. Change the password is an on-demand request. Considering the number of PuKs is unknown, am I wrong thinking the associative array is a valid approach or it would be better a nested table of records with two elements (PuK,encrypted password), or may be two lists (2 sql types): one of Puks (IN) and other for encrypted password (OUT) where the index i would be the reference for the two list? Would you use dbms_scheduler to call operative system utilities in this case? Any comment will be welcome. Thanks in advance.
and I don't know what dbms_scheduler would be invoking - if you want to encrypt, we do encryption already - dbms_crypto, there would be nothing at the OS level to invoke. collection parameters July 1, 2009 - 4am Central time zone Reviewer: Carmen Thanks Tom, N-1 will be the number of end users (application users) that will connect to same database user, whose password it's being changed. As each end user has its own pair public / private key, and as the encryption algorithm is RSA(asymmetric => public key for encripting and a private key for decrypting) then I have to encrypt the random generated password with N-1 public keys (puk). This is the reason for what I am using the plsql types: type t_listapuk as table of varchar2(300); type t_listaenc as table of varchar2(150); Following documentation dbms_crypto only supports Symmetric algorithms (encryption key=decription key), so the only way to encrypt with RSA will be using operative system tools (openssl). I have implemented a job (dbms_scheduler), which calls a program with an argument, an its value (will be the puk) changes for each job execution, it means N-1 job runs with flag use_current_session = true, because with false, trying to read into the out parameter the file generated by the script fires ORA-29283 (file has not been generated yet). Basically: LOOP write_file_puk dbms_scheduler.set_job_argument_value dbms_scheduler.run_job read_file_encrypted END It works, but, I have doubts about the efficiency (2 seconds for each iteration , shell script runs in 0.04 seconds). Could I define an out argument for the program that sets the value for the collection without reading it from plsql? Besides, this is the session information, after several runs (with 2 or 3 puks): NAME SID Bookmark | Bottom | Top
44 de 45
07/01/2011 16:51
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_I...
STATISTIC# VALUE -------------------------------------------------- ----- ---------- ---------session uga memory 198 20 1010328 session uga memory max 198 21 2254552 session pga memory 198 25 1740616 session pga memory max 198 26 2723656 Do you think the resources use is acceptable? Thanks again for your help.
Write a Review
All information and materials provided here are provided "as-is"; Oracle disclaims all express and implied warranties, including, the implied warranties of merchantability or fitness for a particular use. Oracle shall not be liable for any damages, including, direct, indirect, incidental, special or consequential damages for loss of profits, revenue, data or data use, incurred by you or any third party in connection with the use of this information or these materials.
45 de 45
07/01/2011 16:51