用值动态填充列的占位符
Posted
技术标签:
【中文标题】用值动态填充列的占位符【英文标题】:populate placeholders for a column with values dynamically 【发布时间】:2014-02-18 00:50:45 【问题描述】:我有以下包含错误代码和相关错误消息的表结构:
ERR_CODE ERR_MESSAGE
CN001 Invalid Username :USERNM
CN002 Invalid Password :PWD
在我的 PLSQL 代码中,我想动态替换用户名和密码的值。
我知道 EXECUTE IMMEDIATE 可以通过 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;
或者我可以将其分解为 2 个步骤:
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;
基本上,我正在尝试减少所涉及的步骤数量,或者获得性能更好的查询或方法。
提前致谢!
【问题讨论】:
不确定我是否希望任何系统在任何情况下都以明文形式报告用户密码。您的系统应处理密码,然后将其丢弃,而不会将其记录或在错误消息中公开。 【参考方案1】:不,execute immediate
声明在这种情况下将无济于事。此外,实际上没有必要使用它——一切(选择列表、表名)在编译时都是已知的,它只归结为字符串替换。使用静态查询,而不是动态查询。为了进行替换(或字符串格式化),您至少有两个选择:
只需使用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;
结果:
Invalid Username new value
如果可能,更新error_messages
表的err_message
列,将:USERNM
和:PWD
以及其他类似的子字符串替换为%s
(字符文字的占位符)或@987654331 表示占位符@(整数文字的占位符,如果有的话)并使用 utl_lms 包,特别是 format_message()
函数:
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_goes_here
【讨论】:
谢谢尼古拉斯!第二种方法对我来说听起来不错。我在 Java 中使用过类似的东西(MessageFormat.format()),从来不知道他们在 DB 中有类似的东西。【参考方案2】:您可以通过 SELECT 从表中获取 ERR_MESSAGE 并将 userName 或 PWD 附加到它。下面是一个sn-p。
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_output
。
【讨论】:
以上是关于用值动态填充列的占位符的主要内容,如果未能解决你的问题,请参考以下文章