plsql 中的条件字符串,如 sprintf
Posted
技术标签:
【中文标题】plsql 中的条件字符串,如 sprintf【英文标题】:Conditional strings in plsql like sprintf 【发布时间】:2016-09-08 01:58:00 【问题描述】:写下面的代码给了我错误提示:
PL/SQL:语句被忽略 PLS-00382:表达式类型错误:
代码:
if ( l_vol = 0 )
then
l_cndtn_string := 'l_wgt > l_wgt_limit';
else
l_cndtn_string := '(l_wgt > l_wgt_limit) and (l_vol > l_vol_limit)';
end if;
if ( l_cndtn_string )
then
l_isis_task := 'PO';
else
l_isis_task := 'TO';
end if;
【问题讨论】:
【参考方案1】:If statement 计算 boolean expression。在你的例子中
if ( l_cndtn_string )
l_cndtn_string
不是布尔表达式,而是character expression,它们之间没有隐式转换。
请自行检查Expressions。
我不知道您的逻辑是什么,但以下示例向您展示了一种将字符表达式转换为布尔表达式的方法:
if l_cndtn_string is not null -- a boolean expression
then
null;
else
null;
end if;
【讨论】:
【参考方案2】:您想要动态条件构建。在plsql
,和其他编译语言一样,很难做到。
试试这样:
if ( l_vol = 0 )
then
if(l_wgt > l_wgt_limit) then
l_isis_task := 'PO';
end if;
else
if(l_wgt > l_wgt_limit and l_vol > l_vol_limit) then
l_isis_task := 'TO';
end if;
end if;
【讨论】:
【参考方案3】:IF
之后是布尔表达式,而不是字符串 - 这就是您收到 PLS-00382 错误的原因。您当然可以尝试使用动态 sql 动态评估您的表达式,但实际上您想要的很简单:
if ( l_wgt > l_wgt_limit and ( l_vol = 0 or l_vol > l_vol_limit ) )
then
l_isis_task := 'PO';
else
l_isis_task := 'TO';
end if;
【讨论】:
【参考方案4】:哦,只有在阅读其他答案后,我才意识到这个问题是关于什么的。我决定也保留我原来的答案,因为关于 if 语句中字符表达的观点仍然正确。
其他答案是正确的,即使用动态 PL/SQL 构建基于字符串评估的逻辑通常不是一个好主意。他们也提出了正确的解决方案,但恕我直言,存在更好的方法。
通常当我在 PL/SQL 中有多个条件时,我会为条件命名。请参阅下面说明该技术的示例。这些名称使代码能够自我记录,并且极大地提高了代码的可读性,就像现在通常将条件读取为人类语言一样。
declare
v_volume number := 0;
v_weight number := 1;
v_weight_limit constant number := 10;
v_volume_limit constant number := 10;
v_has_volume constant boolean := v_volume > 0;
v_exceed_weight_limit constant boolean := v_weight > v_weight_limit;
v_exceed_volume_limit constant boolean := v_volume > v_volume_limit;
begin
-- no guarantee the logic is the same than in question
-- but just illustrates the coding style
if v_has_volume
and v_exceed_weight_limit
and v_exceed_volume_limit
then
null; -- something
else
null; -- something else
end if;
end;
/
【讨论】:
以上是关于plsql 中的条件字符串,如 sprintf的主要内容,如果未能解决你的问题,请参考以下文章