是否可以执行对象类型的select into表?

时间:2015-05-18 13:55:54

标签: oracle plsql

所以我有一个类型

create or replace type body T_Some_type is object
  (...fields)

我有一个由T_Some_type

类型的行组成的表类型
create or replace TYPE T_Some_Table IS TABLE OF T_Some_type;

我希望从某个视图中选择行到此T_Some_Table

select * 
        into T_Some_Table
        from V_Some_View

这是否可能,并且这样做是否有任何缺点(如果可能的话)。 T_Some_Type中的列必须与V_Some_View中的列相同,或者如果列的名称相同,plsql会在此处进行绑定吗?

如果不可能,会有什么替代方案?

编辑:假定定义了主体,它们不在此处,因为它们与问题无关。

3 个答案:

答案 0 :(得分:7)

是的,确实如此。您需要将列包装在对象的构造函数中,并使用BULK COLLECT语句中的SELECT选项:

CREATE OR REPLACE TYPE t_some_type AS OBJECT(f varchar2(10))
/

CREATE OR REPLACE TYPE t_some_table IS TABLE OF t_some_type
/

DECLARE
   v_some_table t_some_table;
BEGIN
   SELECT t_some_type (dummy)
   BULK   COLLECT INTO v_some_table
   FROM   DUAL;
END;

另外,您还需要确保创建对象规范,而不仅仅是正文(如示例所示)。

SELECT中的列必须与对象构造函数中的列相同。如果您没有明确定义构造函数,那么显式存在一个构造函数,其中每个列都按照规范中声明的顺序存在。

使用此功能的唯一缺点是大量行将导致大量内存使用。如果您希望使用它来处理大量行,则应使用带有LIMIT子句的循环。

除了规范中的列列表外,还可以指定显式构造函数。构造函数可以包含您定义的任何输入,因此,显然,当您使用显式构造函数时,您必须遵循它的参数列表。这是一个例子:

CREATE OR REPLACE TYPE t_some_type AS OBJECT
(
   f1 VARCHAR2 (10),
   CONSTRUCTOR FUNCTION t_some_type (p_length NUMBER, p_value VARCHAR2)
      RETURN SELF AS RESULT
);
/

CREATE OR REPLACE TYPE BODY t_some_type AS
   CONSTRUCTOR FUNCTION t_some_type (p_length NUMBER, p_value VARCHAR2)
      RETURN SELF AS RESULT IS
   BEGIN
      self.f1 := LPAD (p_value, p_length, p_value);
      RETURN;
   END t_some_type;
END;
/

CREATE OR REPLACE TYPE t_some_table IS TABLE OF t_some_type
/

DECLARE
   v_some_table t_some_table;
BEGIN
   --Explicit Constructor
   SELECT t_some_type (10, dummy)
   BULK   COLLECT INTO v_some_table
   FROM   DUAL;
   DBMS_OUTPUT.put_line (v_some_table (1).f1);

   --Implicit Constructor
   SELECT t_some_type (dummy)
   BULK   COLLECT INTO v_some_table
   FROM   DUAL;
   DBMS_OUTPUT.put_line (v_some_table (1).f1);
END;

答案 1 :(得分:0)

OP可能或多或少地希望做到这一点:

SELECT *
  BULK COLLECT INTO v_some_table
  FROM <some_source_table>;

有关更多详细信息,请参见:https://blogs.oracle.com/oraclemagazine/on-bulk-collect-在Oracle 12.1中为我工作。

答案 2 :(得分:0)

您可以通过示例选择设置字段

CREATE OR REPLACE TYPE t_some_type AS OBJECT(f varchar2(10), y varchar2(10))
/

CREATE OR REPLACE TYPE t_some_table IS TABLE OF t_some_type
/

DECLARE
   v_some_table t_some_table;
   v_counter int;
BEGIN
   SELECT t_some_type (column_1, column_2)
   BULK   COLLECT INTO v_some_table
   FROM   some_table;

   -- show the count data fetched

   dbms_output.put_line( 'counter value: ' || to_char(v_counter));

END;