views:

444

answers:

2

Simply trying to get a cursor back for the ids that I specify.

CREATE OR REPLACE PACKAGE some_package AS

  TYPE t_cursor IS REF CURSOR;
  TYPE t_id_table IS TABLE OF NVARCHAR(38) INDEX BY PLS_INTEGER;

  PROCEDURE someentity_select(
    p_ids     IN  t_id_table, 
    p_results OUT t_cursor);

END;

CREATE OR REPLACE PACKAGE BODY some_package AS

  PROCEDURE someentity_select(
    p_ids     IN  t_guid_table, 
    p_results OUT t_cursor)
  IS
  BEGIN

    OPEN p_results FOR 
      SELECT * 
      FROM someschema.someentity 
      WHERE id IN (SELECT column_value FROM TABLE(p_ids)); - fails here

  END;

END;

Note: someschema.someentity.id is a NVARCHAR2(38)

PL/SQL: ORA-00382: expression is of wrong type
PL/SQL: ORA-22905: cannot access rows from a non-nested table item

Where am I going wrong?

+4  A: 

You can only SELECT from a collection type that is defined in the database via a CREATE TYPE statement, not an associative array:

CREATE TYPE t_id_table IS TABLE OF NVARCHAR(38);

CREATE OR REPLACE PACKAGE some_package AS

  PROCEDURE someentity_select(
    p_ids     IN  t_guid_table, 
    p_results OUT SYS_REFCURSOR);

END;

CREATE OR REPLACE PACKAGE BODY some_package AS

  PROCEDURE someentity_select(
    p_ids     IN  t_guid_table, 
    p_results OUT SYS_REFCURSOR)
  IS
  BEGIN

    OPEN p_results FOR 
      SELECT * 
      FROM someschema.someentity 
      WHERE id IN (SELECT column_value FROM TABLE(p_ids));

  END;

END;
Tony Andrews
Thanks.. but now it shows ORA-12714: invalid national character set specified on that line.. much closer though.
Travis Heseman
You may want to post another question about that, as it is a totally different problem and I have no clue about national character set issues.
Tony Andrews
A: 

This is an index-by table, which is a PL/SQL type.

You can only use SQL types in the SQL engine of Oracle. Or PL/SQL types, that Oracle can hack around to look like SQL types.

You can have a simple array-like collection and use it as a result. (no index by)

type TGuidList is table of NVarchar(38);

But the best compatibility and stability, you get by declaring it as a global SQL type and use that inside your package:

create type TGuidList is table of NVarchar(38);

Edit: You will not need an NVarChar for a GUID, will you? A good ol' VarChar should do the trick just fine.

Robert Giesecke
I have to use NVarchar2 - it's part of my client's archaic database standard (which is also why I'm using SPs at all).
Travis Heseman