oracle – PLSQL中的反思?

前端之家收集整理的这篇文章主要介绍了oracle – PLSQL中的反思?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一个过程来处理存储在ANYDATA中的用户定义对象.对象类型和属性名称只能在运行时知道,因此我无法在declare部分中为它定义viarable.在 Java中,我可以使用反射来处理它,我可以知道类名和字段名.然后我可以通过反射访问这些字段.有没有办法在PLsql中这样做?我现在脑子里想的是在程序中动态创建一个sql字符串并执行它.但这不是我想要的.

假设用户A将ADT类型定义为创建或替换类型Person_type作为对象(fname varchar2(10),lname varchar2(10));并创建一个对象实例并将其插入ANYDATA.

在我的程序中,不知怎的,我知道我需要处理这个对象的第一个属性,即fname.因此,如果首先知道adt类型,我的代码将是:

declare
  adobject A.Person_type; -- HERE! I don't know the type yet,so I can't define adobject!
  tempAnydata anydata;
  rt number;
  vbuffer varchar2(10);
  ...
begin
   select somecolumn 
   into tempAnydata 
   from soMetable 
   where something='something' for update;

   rt := tempAnydata.GetObject(adobject);

   vbuffer := adobject.fname; -- HERE! I don't know the attribute name is fname!
   -- deal with vbuffer here
end;

那么我应该怎样做才能动态地制作它呢?提前致谢.

您需要使用ANYTYPE来描述ANYDATA并确保类型正确.然后,您可以使用piecewise和getVarchar2访问该属性.

下面的大多数代码用于检查类型,如果您不关心类型安全性,则不需要该类型.

函数返回值:

create or replace function get_first_attribute(
    p_anydata in out anydata --note the "out" - this is required for the "piecewise"
) return varchar2 is
    v_typecode pls_integer;
    v_anytype anytype;
begin
    --Get the typecode,and the ANYTYPE
    v_typecode := p_anydata.getType(v_anytype);

    --Check that it's really an object
    if v_typecode = dbms_types.typecode_object then
        --If it is an object,find the first item
        declare
            v_first_attribute_typecode pls_integer;
            v_aname          varchar2(32767);
            v_result         pls_integer;
            v_varchar        varchar2(32767);
            --Variables we don't really care about,but need for function output
            v_prec           pls_integer; 
            v_scale          pls_integer;
            v_len            pls_integer;
            v_csid           pls_integer;
            v_csfrm          pls_integer;
            v_attr_elt_type  anytype;
        begin
            v_first_attribute_typecode := v_anytype.getAttrElemInfo(
                pos            => 1,--First attribute
                prec           => v_prec,scale          => v_scale,len            => v_len,csid           => v_csid,csfrm          => v_csfrm,attr_elt_type  => v_attr_elt_type,aname          => v_aname);

            --Check typecode of attribute
            if v_first_attribute_typecode = dbms_types.typecode_varchar2 then
                --Now that we've verified the type,get the actual value.
                p_anydata.piecewise;
                v_result := p_anydata.getVarchar2(c => v_varchar);

                --DEBUG: Print the attribute name,in case you're curIoUs
                --dbms_output.put_line('v_aname: '||v_aname);

                return v_varchar;
            else
                raise_application_error(-20000,'Unexpected 1st Attribute Typecode: '||
                    v_first_attribute_typecode);
            end if;
        end;
    else
        raise_application_error(-20000,'Unexpected Typecode: '||v_typecode);
    end if;
end;
/

类型:

create or replace type Person_type as object (fname varchar2(10),lname varchar2(10));

create or replace type other_type as object (first_name varchar2(10),poetry clob);

测试运行:

declare
    --Create records
    v_type1 person_type := person_type('Ford','Prefect');
    v_type2 other_type := other_type('Paula','blah blah...');
    v_anydata anydata;
begin
    --Convert to ANYDATA.
    --Works as long as ANYDATA is an object with a varchar2 as the first attribute.
    v_anydata := anydata.convertObject(v_type1);
    dbms_output.put_line(get_first_attribute(v_anydata));

    v_anydata := anydata.convertObject(v_type2);
    dbms_output.put_line(get_first_attribute(v_anydata));
end;
/

输出

Ford
Paula

猜你在找的Oracle相关文章