【问题标题】:Using an Oracle Table Type in IN-clause - compile fails在 IN 子句中使用 Oracle 表类型 - 编译失败
【发布时间】:2011-01-03 23:18:53
【问题描述】:

只需尝试为我指定的 id 取回光标。

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;

注意:someschema.someentity.id 是 NVARCHAR2(38)

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

我哪里错了?

【问题讨论】:

    标签: oracle plsql associative-array database-cursor


    【解决方案1】:

    在 12.2 之前的 Oracle 版本中,您只能从通过 CREATE TYPE 语句在数据库中定义的集合类型中选择,不能关联数组:

    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;
    

    【讨论】:

    • 谢谢.. 但现在它显示 ORA-12714: invalid national character set specified on that line.. 更接近了。
    • 您可能想发布另一个关于此的问题,因为这是一个完全不同的问题,我对国家字符集问题一无所知。
    • 注意:在 12.2 及更高版本中,您现在可以在 TABLE 运算符中使用整数索引的关联数组!
    • @StevenFeuerstein 谢谢 - 我也更新了答案
    【解决方案2】:

    这是一个索引表,它是一种PL/SQL类型。

    您只能在 Oracle 的 SQL 引擎中使用 SQL 类型。或者 PL/SQL 类型,Oracle 可以修改它以看起来像 SQL 类型。

    您可以拥有一个简单的类似数组的集合并将其用作结果。 (无索引)

    type TGuidList is table of NVarchar(38);
    

    但最好的兼容性和稳定性,您可以通过将其声明为全局 SQL 类型并在您的包中使用它来获得:

    创建类型 TGuidList 是 NVarchar(38) 的表;

    编辑:GUID 不需要 NVarChar,对吗?一个好的 ol' VarChar 应该可以解决问题。

    【讨论】:

    • 我必须使用 NVarchar2 - 它是我客户的古老数据库标准的一部分(这也是我使用 SP 的原因)。
    猜你喜欢
    • 2012-12-03
    • 2023-03-09
    • 2015-03-13
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多