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的主要内容,如果未能解决你的问题,请参考以下文章

PHP 格式化字符串sprintf()

JavaScript Javascript中的Sprintf(字符串格式)

Javascript中的Sprintf(字符串格式)

带有动态字符串的 sprintf()

字符与数字的转换:sprintf和sscanf

你知道如何用C语言将格式化数据和字符串相互转换吗?