2016-09-08 5 views
-3

Пишущие ниже код дает мне ошибку говоря:Условные строки в PLSQL как Sprintf

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; 

ответ

0

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; 
0

Вы хотите динамическое условие сборки. В 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; 
0

После 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; 
0

О, только после прочтения других ответов, я понял, что этот вопрос был о. Я решил также сохранить свой первоначальный ответ, поскольку точка в выражении символа в if-statement по-прежнему правильная.

Другие ответы верны, что создание логики, основанной на оценке строк с динамическим 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; 
/
Смежные вопросы