PL / SQL在匿名块内创建对象

时间:2014-12-09 15:38:49

标签: object plsql block anonymous

我是Oracle SQL DEVELOPER的新手,我无法在匿名块中创建对象。 在此页面Oracle Database Object-Relational Developer's Guide

    CREATE TYPE address_typ AS OBJECT ( 
   street          VARCHAR2(30),
   city            VARCHAR2(20),
   state           CHAR(2),
   postal_code     VARCHAR2(6) );
/
CREATE TYPE employee_typ AS OBJECT (
  employee_id       NUMBER(6),
  first_name        VARCHAR2(20),
  last_name         VARCHAR2(25),
  email             VARCHAR2(25),
  phone_number      VARCHAR2(20),
  hire_date         DATE,
  job_id            VARCHAR2(10),
  salary            NUMBER(8,2),
  commission_pct    NUMBER(2,2),
  manager_id        NUMBER(6),
  department_id     NUMBER(4),
  address           address_typ,
  MAP MEMBER FUNCTION get_idno RETURN NUMBER,
  MEMBER PROCEDURE display_address ( SELF IN OUT NOCOPY employee_typ ) );
/
CREATE TYPE BODY employee_typ AS
  MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
  BEGIN
    RETURN employee_id;
  END;
  MEMBER PROCEDURE display_address ( SELF IN OUT NOCOPY employee_typ ) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE(first_name || ' '  || last_name);
    DBMS_OUTPUT.PUT_LINE(address.street);
    DBMS_OUTPUT.PUT_LINE(address.city || ', '  || address.state || ' ' ||
                         address.postal_code);   
  END;
END;
/
CREATE TABLE employee_tab OF employee_typ;

和...

--Requires the top code
DECLARE
  emp employee_typ; -- emp is atomically null
BEGIN
-- call the constructor for employee_typ
  emp := employee_typ(315, 'Francis', 'Logan', 'FLOGAN',
        '415.555.0100', '01-MAY-04', 'SA_MAN', 11000, .15, 101, 110, 
         address_typ('376 Mission', 'San Francisco', 'CA', '94222'));
  DBMS_OUTPUT.PUT_LINE(emp.first_name || ' ' || emp.last_name); -- display details
  emp.display_address();  -- call object method to display details
END;
/

有2个独立的代码块(示例3-1使用对象类型和示例3-2在PL / SQL块中声明对象)。我怎么能把它全部放在一个匿名区块?

我不能在匿名块的范围内创建对象,使用它并将它们删除吗?

2 个答案:

答案 0 :(得分:4)

您无法在匿名块中执行直接DDL。您应该使用动态SQL:

declare
  l_sql varchar2(2000);
begin
  l_sql := 'CREATE TYPE address_typ AS OBJECT ( 
   street          VARCHAR2(30),
   city            VARCHAR2(20),
   state           CHAR(2),
   postal_code     VARCHAR2(6) )';

  execute immediate l_sql;

end;

所以把你的每个"创建类型"在动态SQL中它应该做你想要的!

答案 1 :(得分:4)

如果你只需要一个临时数据结构,你可以在块级声明中使用记录类型,不太可读和限制,但可以用于一些简单的东西

declare

  type address_typ is record(
   street          VARCHAR2(30),
   city            VARCHAR2(20),
   state           CHAR(2),
   postal_code     VARCHAR2(6)  
  );

  TYPE employee_typ is record (
    employee_id       NUMBER(6),
    first_name        VARCHAR2(20),
    last_name         VARCHAR2(25),
    email             VARCHAR2(25),
    phone_number      VARCHAR2(20),
    hire_date         DATE,
    job_id            VARCHAR2(10),
    salary            NUMBER(8,2),
    commission_pct    NUMBER(2,2),
    manager_id        NUMBER(6),
    department_id     NUMBER(4),
    address           address_typ/*,
    MAP MEMBER FUNCTION get_idno RETURN NUMBER,
    MEMBER PROCEDURE display_address ( SELF IN OUT NOCOPY employee_typ ) */
  );

  emp employee_typ;

begin 
  emp.employee_id := 315;
  emp.first_name := 'Francis';
  emp.last_name := 'Logan';
  --and so on for the others fields

  emp.address.street := '376 Mission';
  emp.address.city := 'San Francisco';
  emp.address.state := 'CA';
  emp.address.postal_code := '94222';

  DBMS_OUTPUT.PUT_LINE(emp.first_name || ' ' || emp.last_name);
  --no member available so you have to print each field
  DBMS_OUTPUT.PUT_LINE(emp.address.street);
  DBMS_OUTPUT.PUT_LINE(emp.address.city || ', '  || emp.address.state || ' ' ||  emp.address.postal_code);  
end;