ORA-06550 using a nested table type - oracle

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

Related

oracle sql: collect aggregation

I want to group my database entries by an attribute and to know which entries are in each group at the same time. I collect the ids of the grouped entries with Oracle COLLECT function COLLECT Function
DECLARE
TYPE ids_type IS TABLE OF number(19, 0);
ids ids_type;
BEGIN
select cast(collect(r.id) as ids_type) into ids from rechnungsdaten r group by r.status;
END;
But then I get the error:
Error report - ORA-06550: Line 5, Column 44: PL/SQL:
ORA-00902: Invalid datatype ORA-06550: Line 5, Column 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
What is wrong here?
You cannot use COLLECT function on a type declared in a PL/SQL anonymous block.
You have other options like
Create a database type and run your collect query.
create or replace TYPE ids_type IS TABLE OF number(19, 0);
SELECT
r.status,
CAST(COLLECT(r.id) AS ids_type)
FROM
rechnungsdaten r
GROUP BY
r.status;
Use a simple LISTAGG query to see the list of ids as a string
SELECT
r.status,
LISTAGG(r.id,',') WITHIN GROUP(
ORDER BY
id
)
FROM
rechnungsdaten r
GROUP BY
r.status;
Demo

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-22905 on setting Count(*) into out param

I've created a sample oracle function to returns the number of records in a table. Here is it
create or replace FUNCTION TEST_COUNT
RETURN NUMBER AS recCount NUMBER;
BEGIN
SELECT COUNT(*) INTO recCount FROM **tableName**;
return recCount;
END TEST_COUNT;
Its' being compiled successfully, but when I called this function in Oracle SQL-Developr using command
SELECT * FROM TABLE (TEST_COUNT());
it threw me the following error.
ORA-22905: cannot access rows from a non-nested table item
22905. 00000 - "cannot access rows from a non-nested table item"
*Cause: attempt to access rows of an item whose type is not known at
parse time or that is not of a nested table type
*Action: use CAST to cast the item to a nested table type
Error at Line: 1 Column: 22
I've followed Oracle error ORA-22905: cannot access rows from a non-nested table item but can't reach the solution. Please suggest what should I do?
Well, you're just calling it wrong. The TABLE() table collection expression is used when the function returns a collection (e.g. from create type x as table of number) that you want to treat as a table so you can join against it, which isn't the case here; you're returning a simple NUMBER.
So just do:
SELECT TEST_COUNT FROM DUAL;

PL/SQL: ORA-22905: cannot access rows from a non-nested table item [duplicate]

In an Oracle package I have defined a type
type setTable is table of my_sets.pkey%type;
in the package declaration (the non-body part). The pkey column referenced is a number(38). Then in a function in the package body I have
...
with d as (select column_value from table(sets)),
...
where sets is a parameter to the function of type settable. This line fails to compile with the error 'ORA-22905: cannot access rows from a non-nested table item'. What can I do to resolve this?
The select statement is SQL not PL/SQL, and the SQL engine can only work with types defined on the server like this:
create type setObj is object (<attributes>);
create type setTable is table of setObj;

pl/sql nested table assignment issue in APEX

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()

Resources