You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle PL/SQL如何根据动态字段名获取对象属性值?

在Oracle PL/SQL中动态获取和设置对象字段值的实现方法

Oracle PL/SQL本身没有像JavaScript中l_object[l_field_name]那样的原生语法支持动态访问对象字段,但可以通过动态SQL实现类似需求,以下是两种常用方案:

方案一:直接在PL/SQL块中使用动态SQL

通过拼接动态SQL语句,结合EXECUTE IMMEDIATE执行,实现字段的动态获取和赋值。

动态获取字段值

declare
    l_object t_my_type := t_my_type(33, 77);
    l_field_name varchar2(255 char) := 'num_val_b';
    l_result number;
begin
    -- 拼接并执行动态查询,绑定对象变量获取字段值
    execute immediate 'select :obj.' || l_field_name || ' from dual'
        into l_result
        using l_object;
    dbms_output.put_line(l_result); -- 输出77
end;
/

动态设置字段值

declare
    l_object t_my_type := t_my_type(33, 77);
    l_field_name varchar2(255 char) := 'num_val_b';
    l_new_value number := 99;
begin
    -- 拼接并执行动态赋值语句,绑定对象和新值
    execute immediate 'begin :obj.' || l_field_name || ' := :new_val; end;'
        using in out l_object, l_new_value;
    dbms_output.put_line(l_object.num_val_b); -- 输出99
end;
/

方案二:给自定义类型添加成员方法

将动态逻辑封装到对象类型的成员方法中,调用更符合面向对象风格,同时可增加字段校验逻辑。

第一步:修改对象类型,添加成员方法

create or replace type t_my_type force as object
(
    num_val_a  number(30),
    num_val_b  number(30),
    -- 动态获取数值字段的方法
    member function get_num_value_by_name(p_field_name varchar2) return number,
    -- 动态设置数值字段的方法
    member procedure set_num_value_by_name(p_field_name varchar2, p_new_value number)
);
/

create or replace type body t_my_type is
    member function get_num_value_by_name(p_field_name varchar2) return number is
        l_result number;
    begin
        -- 校验字段是否存在,避免无效字段名
        if not exists (
            select 1 from user_type_attrs 
            where type_name = 'T_MY_TYPE' and attr_name = upper(p_field_name)
        ) then
            raise_application_error(-20001, '无效字段名: ' || p_field_name);
        end if;
        
        execute immediate 'select self.' || p_field_name || ' from dual' into l_result;
        return l_result;
    exception
        when others then
            raise_application_error(-20001, '获取字段值失败: ' || sqlerrm);
    end;

    member procedure set_num_value_by_name(p_field_name varchar2, p_new_value number) is
    begin
        -- 校验字段合法性
        if not exists (
            select 1 from user_type_attrs 
            where type_name = 'T_MY_TYPE' and attr_name = upper(p_field_name)
        ) then
            raise_application_error(-20002, '无效字段名: ' || p_field_name);
        end if;
        
        execute immediate 'begin self.' || p_field_name || ' := :new_val; end;' using p_new_value;
    exception
        when others then
            raise_application_error(-20002, '设置字段值失败: ' || sqlerrm);
    end;
end;
/

第二步:调用成员方法实现动态操作

declare
    l_object t_my_type := t_my_type(33, 77);
    l_field_name varchar2(255 char) := 'num_val_b';
begin
    -- 动态获取字段值
    dbms_output.put_line(l_object.get_num_value_by_name(l_field_name)); -- 输出77
    
    -- 动态设置字段值
    l_object.set_num_value_by_name('num_val_a', 55);
    dbms_output.put_line(l_object.num_val_a); -- 输出55
end;
/

注意事项

  • 动态SQL拼接时,建议通过USER_TYPE_ATTRS视图校验字段名合法性,避免SQL注入或无效字段错误。
  • 如果对象包含不同数据类型的字段,需扩展方法以支持多类型处理,或新增对应类型的成员方法。

内容的提问来源于stack exchange,提问作者DZN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:41:20