pl/sql nested table assignment issue in APEX - oracle

All,
I've been fighting this issue for a little while, now, and it seems like there's something simple I'm missing, but I haven't been able to figure it out.
I'm trying to use a pl/sql nested table in APEX to collate and return data from disparate tables to a page view.
As a test, I created a nested table object and type:
CREATE OR REPLACE TYPE "E_TEST" as object (
col1 varchar2(8),
col2 varchar2(16)
)
/
CREATE OR REPLACE TYPE "E_TEST_TAB" as table of e_test
/
When I attempt to populate the nested table with this code:
declare
l_test e_test_tab := e_test_tab();
begin
l_test.extend;
l_test(l_test.last) := e_test_tab('testing','testing12345');
end
I get these errors:
ORA-06550: line 5, column 24:
PLS-00306: wrong number or types of arguments in call to 'E_TEST_TAB'
ORA-06550: line 5, column 24:
PLS-00306: wrong number or types of arguments in call to 'E_TEST_TAB'
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
I've been searching for an answer for a couple of days, but everything I can see says I'm creating and populating the object correctly, and searches related to the PLS-00306 error don't return much specific to the nested table context. I'm new to pl/sql, so there's a high probability that I've missed something simple, but the folks I know who might be able to help me don't use a lot of collections, so they're stumped by this one, as well.
Thanks in advance for your assistance.
Justin

declare
l_test e_test_tab := e_test_tab();
begin
l_test.extend;
l_test(l_test.last) := e_test('testing','testing12345');
end;
/
It has to be e_test() while assignment of individual record.
Only while initializing the nested collection we use e_test_tab()

Related

record linking to each other in PL/SQL Developer

There was a need to create records in PL / SQL Developer, which refer to each other. I started to understand all this recently, therefore there were doubts about the achievement of this goal, but also the thought was spinning in my head that I was not the first to ask this question. Therefore, if you know how to do it or have ideas for implementation, I will be very glad of your help, but for now I will continue to google.
Example:
TYPE rtype1 IS RECORD
(
/*some code*/
r_type2 rtype2;
);
TYPE rtype2 IS RECORD
(
/*some code*/
r_type1 rtype1;
);
Additional Information:
The fact is that, on the basis of xsd schemes, you need to generate records and collections, but because In the xsd scheme this is not prohibited, such a need has arisen. And it is necessary to create types, and not to use the tools for working with xml.
You can use forward declaration to declare the existence of a type in PL/SQL before you fully specify it. Like this:
DECLARE
TYPE rtype2; -- Forward declaration
TYPE rtype1 IS RECORD( r_type2 rtype2 );
TYPE rtype2 IS RECORD( r_type1 INTEGER );
BEGIN
NULL;
END;
/
However, you cannot use this to declare a non-REF mutually recursive type; if you try this:
DECLARE
TYPE rtype2;
TYPE rtype1 IS RECORD( r_type2 rtype2 );
TYPE rtype2 IS RECORD( r_type1 rtype1 );
BEGIN
NULL;
END;
/
Then you get the error:
ORA-06550: line 4, column 18:
PLS-00318: type "RTYPE2" is malformed because it is a non-REF mutually recursive type
ORA-06550: line 4, column 3:
PL/SQL: Item ignored
You can do it using object data types and a REF in the SQL scope:
CREATE TYPE otype1; -- Forward declaration
CREATE TYPE otype2 IS OBJECT( o_type1 REF otype1 );
CREATE OR REPLACE TYPE otype1 IS OBJECT( o_type2 otype2 );
But, again, if you try to use a non-REF mutually recursive type:
CREATE TYPE otype1;
CREATE TYPE otype2 IS OBJECT( o_type1 otype1 );
/* ORA-24344: success with compilation error */
CREATE TYPE otype1 IS OBJECT( o_type2 otype2 );
/* ORA-04055: Aborted: "OTYPE1" formed a non-REF mutually-dependent cycle with "OTYPE2". */
Then it doesn't work.
db<>fiddle here
Yes, you can define a type and then reference it in another type, which you define later in the code or on the system. However, as Alex asked, what are you trying to accomplish? -- Also contrary to what mathguy posted you can create and use types whose definitions are co-dependent. I do not recommend doing so, but ...
From the documentation:
An incomplete type is a type created by a forward type definition. It is called incomplete because it has a name but no attributes or methods. It can be referenced by other types, allowing you define types that refer to each other. However, you must fully specify the type before you can use it to create a table or an object column or a column of a nested table type.

Oracle SQL: Stored procedure - object invalid

I was just about to create a store procedure and it worked so far.
(For learning purposes I want to hand a credit card number over to a stored procedure which should return the associated customer identification number.)
But when I wanted to test this procedure using
BEGIN CC_TO_CID(:p1, :p2);
END;
(the input data was submitted via a dialogue of my SQL IDE)
it just returned:
SQL Error [6550][65000]: ORA-06550: Row 1, Column 7: PLS-00905
Object xyz.CC_TO_CID is invalid ORA-06550: Row 1, Column 7:
PL/SQL: Statement ignored
This basically means that my stored procedure isn't well formatted but I really don't have any clue.
My stored procedure:
CREATE OR REPLACE PROCEDURE CC_TO_CID(in_cc_nr IN NUMBER(16,0), out_cid OUT NUMBER) IS
BEGIN
SELECT PM.CUSTOMER_ID INTO cid FROM "2_PAYMENT_M" PM,
"2_CREDITCARD" CC
WHERE CC.CC_NR=in_cc_nr AND CC.PAYMENT_M_NR=PM.PAYMENT_M_NR;
END;
My table structure with some test data:
Table: "2_CREDITCARD"
CC_NR PAYMENT_M_NR NAME CVV EXPIRES
------------------ -------------- -------------- ----- ---------------------
5307458270409047 1 Haley Harrah 52 2019-11-01 00:00:00
Table: "2_PAYMENT_M"
PAYMENT_M_NR CUSTOMER_ID CREATED TRANSACTION_LIMIT
-------------- ------------- --------------------- -------------------
1 100 2018-01-21 00:00:00 1.000
Thanks in advance!
I appreciate any useful hints.
You will have seen an error when you compiled the procedure, but it would probably have been quite generic. Your client may support show errors, or you can query the user_errors view to see the details.
You can’t give a size or precision restriction for the data type of a formal parameter to a function or procedure, so NUMBER(10,0) should just be NUMBER; and you have got the name of the argument wrong in your into clause.
CREATE OR REPLACE PROCEDURE CC_TO_CID(in_cc_nr IN NUMBER, out_cid OUT NUMBER) IS
BEGIN
SELECT PM.CUSTOMER_ID
INTO out_cid
FROM "2_PAYMENT_M" PM
JOIN "2_CREDITCARD" CC
ON CC.PAYMENT_M_NR=PM.PAYMENT_M_NR
WHERE CC.CC_NR=in_cc_nr;
END;
I’ve switched to ANSI join syntax because... well, just because. Untested as I don’t have your tables; if it still gets errors then check user_errors again.

Create Type based on an exiting Table

As the title said : I want to create a type in oracle based on an existing Table.
I did as follow :
create or replace type MY_NEW_TYPE as object( one_row EXISTING_TABLE%rowtype);
The Aim is to be able to use this into a function which will return a table containing sample row of the table EXISTING_TABLE :
create or replace function OUTPUT_FCT() return MY_NEW_TYPE AS
...
If you only need to create a function that returns a row from your table, you could try something like the following, without creating types.
setup:
create table EXISTING_TABLE( a number, b varchar2(100));
insert into EXISTING_TABLE values (1, 'one');
function:
create or replace function OUTPUT_FCT return EXISTING_TABLE%rowtype AS
retVal EXISTING_TABLE%rowType;
begin
select *
into retVal
from EXISTING_TABLE
where rownum = 1;
--
return retVal;
end;
function call
SQL> begin
2 dbms_output.put_line(OUTPUT_FCT().a);
3 dbms_output.put_line(OUTPUT_FCT().b);
4 end;
5 /
1
one
However, I would not recommend such an approach, because things like select * can be really dangerous; I would much prefer defining a type with the fields I need, and then explicitly query my table for the needed columns.
No, you can't do that, you'll get a compilation error:
create or replace type my_new_type as object(one_row t42%rowtype);
/
Type MY_NEW_TYPE compiled
Errors: check compiler log
show errors
Errors for TYPE STACKOVERFLOW.MY_NEW_TYPE:
LINE/COL ERROR
-------- -----------------------------------------------------------------------
0/0 PL/SQL: Compilation unit analysis terminated
1/36 PLS-00329: schema-level type has illegal reference to MYSCHEMA.T42
You will need to specify each field in the object type, and you will have to specify the data types manually too - you can't use table.column%type either.
You could create the type dynamically based on column and data type information from the data dictionary, but as this will (hopefully) be a one-off task and not something you'd do at runtime, that doesn't really seem worth it.
You can create a PL/SQL table type based on your table's rowtype, but you would only be able to call a function returning that from PL/SQL, not from plain SQL - so you couldn't use it in a table collection expression for example. If you were only returning a single sample row you could return a record rather than a table, but the same applies. You can also have a function that returns a ref cursor which could match the table's structure, but you wouldn't be able to treat that as a table either.
Read more about object type creation in the documentation. Specifically the attribute and datatype sections.

ORA-06550 using a nested table type

I'm trying to create some output based on select items from APEX.
The case is as follows:
In APEX you select certain items.
APEX makes a nested table of those primary keys and call the function to create the output.
The function generates the output and returns it.
I already found out that I can't use locally defined nested tables in the where clause, but I am now stuck on the following:
My stored type:
CREATE OR REPLACE EDITIONABLE TYPE "T_NUMBERS" as table of NUMBER(10,0)
The part of the function that gives the ORA-06550 error:
DECLARE
c_asked T_NUMBERS;
BEGIN
c_asked := T_NUMBERS(21);
This is just a simple example of what is going wrong.
The error itself:
ORA-06550: line 9, column 23:
PL/SQL: ORA-00932: inconsistent datatypes: expected NUMBER got <schema_name>.T_NUMBERS

For cursor joining tables

could you help me out, can't figure out this one, I get the following error message:
ORA-06550: line 4, column 32:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 3, column 8:
PL/SQL: SQL Statement ignored
ORA-06550: line 11, column 32:
PLS-00364: loop index variable 'V_CUR_SPOKENLANG' use is invalid
ORA-06550: line 11, column 11:
PL/SQL: Statement ignored
Tried to find solution in Oracle Forum and
http://www.techonthenet.com/oracle/errors/ora00942.php
Also tried to do it by this example:
http://www.w3schools.com/sql/sql_join_inner.asp
But got basically the same results.
I have access to both these tables with SELECT.
The code I'm having problems with:
DECLARE
CURSOR cur_spokenlang IS
SELECT country_id, country_name, language_id
FROM wf_countries c, wf_spoken_langugages sl
WHERE c.country_id = sl.country_id;
BEGIN
FOR v_cur_spokenlang IN cur_spokenlang
LOOP
DBMS_OUTPUT.PUT_LINE(v_cur_spokenlang.country_name || ' ' ||
v_cur_spokenlang.country_id || ' ' ||
v_cur_spokenlang.language_id);
END LOOP;
END;
Thank you in advance :)
Either of the tables you mentioned is INVALID (May be invalid schema you run or no PUBLIC SYNONYM).
Also noticing that the country_id is left ambiguous . Needs to be c.country_id.
Please make sure, you have the privileges to the user directly and not via any ROLES. Because, to be access via a PL/SQL the user id needs to have direct SELECT privileges over the tables.!
If you are on windows Use SQLTools IDE. http://www.sqltools.net/
Whenever there is an error.The Cursor directly jump to the point where
the error is.

Resources