Oracle 使用值动态填充列的占位符

Oracle 使用值动态填充列的占位符,oracle,plsql,oracle11g,substitution,execute-immediate,Oracle,Plsql,Oracle11g,Substitution,Execute Immediate,我有以下表格结构,其中包含错误代码和相关错误消息: ERR_CODE ERR_MESSAGE CN001 Invalid Username :USERNM CN002 Invalid Password :PWD 在我的PLSQL代码中,我想动态地替换用户名和密码的值 我知道executeimmediate可以通过USING子句进行替换,但是在这种情况下查询必须是静态的 我正在寻找一种类似于execute immediate的口味,它可以做到这一点: SIMILAR

我有以下表格结构,其中包含错误代码和相关错误消息:

ERR_CODE    ERR_MESSAGE
CN001       Invalid Username :USERNM
CN002       Invalid Password :PWD
在我的PLSQL代码中,我想动态地替换用户名和密码的值

我知道executeimmediate可以通过USING子句进行替换,但是在这种情况下查询必须是静态的

我正在寻找一种类似于execute immediate的口味,它可以做到这一点:

SIMILAR_EXECUTE_IMMDIATE q'{select ERR_MESSAGE from ERROR_MESSAGES where ERR_CODE = 'CN001'}' INTO l_err_msg USING l_curr_user;
或者我可以将其分解为两个步骤:

select ERR_MESSAGE into err_msg_var from ERROR_MESSAGES where ERR_CODE='CN001';

EXECUTE_IMMDIATE err_msg_var INTO l_err_msg USING l_curr_user;
基本上,我试图减少所涉及的步骤数量,或者可能得到一个性能更好的查询或方法


提前谢谢

您只需通过选择并将userName或PWD附加到表中,即可从表中获取ERR_消息。下面是一个片段

select ERR_MESSAGE into err_msg_var from ERROR_MESSAGES where ERR_CODE='CN001';
dbms_output.put_line(err_msg_var||l_curr_user)

如果要将其定义为函数,可以返回
dbms\u输出的值。

否,
executeimmediate
语句在这种情况下没有帮助。除此之外,真的没有必要使用它——一切(选择列表、表名)都是在编译时知道的,它只涉及到字符串替换。使用静态查询,而不是动态查询。要进行替换(或字符串格式设置),您至少有两种选择:

  • 只需使用
    replace()
    函数:

    set serveroutput on;
    clear screen;
    
    declare
       l_result varchar2(50);
    begin
       select err_message
         into l_result
         from error_messages
        where err_code = 'CN001';
    
       dbms_output.put_line(replace(l_result, ':USERNM', 'new value')); 
    end;
    
    set serveroutput on;
    clear screen;
    
    declare
      l_result varchar2(50);
    begin
      select err_message
        into l_result
        from error_messages
       where err_code = 'CN001';
    
      dbms_output.put_line(
         utl_lms.format_message(l_result, 'new_value_goes_here')
       ); 
    end;
    
    结果:

    Invalid Username new value
    
    Invalid Username new_value_goes_here
    
  • 如果可能,通过替换
    :USERNM
    :PWD
    以及其他类似子字符串来更新
    错误消息表的
    errr\u message
    列,用
    %s
    表示占位符(字符文字占位符)或
    %d
    (整数文字占位符,如果有)并使用软件包,特别是
    格式化消息()
    函数:

    set serveroutput on;
    clear screen;
    
    declare
       l_result varchar2(50);
    begin
       select err_message
         into l_result
         from error_messages
        where err_code = 'CN001';
    
       dbms_output.put_line(replace(l_result, ':USERNM', 'new value')); 
    end;
    
    set serveroutput on;
    clear screen;
    
    declare
      l_result varchar2(50);
    begin
      select err_message
        into l_result
        from error_messages
       where err_code = 'CN001';
    
      dbms_output.put_line(
         utl_lms.format_message(l_result, 'new_value_goes_here')
       ); 
    end;
    
    结果:

    Invalid Username new value
    
    Invalid Username new_value_goes_here
    

  • 不确定我是否希望任何系统在任何上下文中以明文形式报告用户密码。您的系统应该处理密码,然后丢弃它,而不记录它或在错误消息中公开它。谢谢Nicholas!第二种方法听起来不错。我在Java中使用了类似的东西(MessageFormat.format()),从来都不知道它们在DB中也有类似的东西。