2017-02-03 4 views
-1

В анонимном блоке у меня есть входная строка, которая пуста/null и хочет проверить ее на непустую строку. Пример:Oracle - Как определить между нулевой и не пустой строкой?

DECLARE 
v_notnull varchar2(50):='this string is never null'; 
v_input varchar2(50):=''; 
BEGIN 
    IF trim(v_input) != trim(v_notnull) THEN 
     dbms_output.put_line('the strings do NOT match'); 
    ELSE 
     dbms_output.put_line('the strings DO match'); 
    END IF; 
END; 

Проблема здесь в том, что, когда я запускаю этот блок, выход всегда 'the strings DO match' хотя я ввод пустой строки '' (ака нуля) в v_input, который не является таким же, как строка 'this string is never null'. Как я могу убедится, что оракул покрывает пустую строку? Когда v_input пуст, я хочу, чтобы выход был 'the strings do NOT match'.

+0

Вопрос заключается в том, что ваш код не будет даже компиляции, что вы означает «выход всегда ...» ??? Вам не хватает длины переменных varchar2, которые вы объявили, и это фатальная ошибка. – mathguy

+0

ОК, люди .... Я печатал это по мобильному телефону. Я исправил это в своем вопросе. –

+0

Это, вероятно, одна из самых кратких ссылок на то, как оракул обрабатывает нулевые сравнения: http://www.morganslibrary.org/reference/null.html –

ответ

3

documentation has a section on null handling. Пустую строку обрабатывают так же, как и null, и вы не можете сравнивать нули (любого типа) с равенством - как показывает таблица в документации, результат сравнения чего-либо с нулем неизвестен - ни истина, ни ложь. Вы должны использовать is [not] null, чтобы сравнить что-либо с нулевым.

В этом случае вы могли бы записать это в явном виде, видя это одна переменная равна нулю, а другой нет, и наоборот, и только сравнить фактические значения, если это говорит вам, ни равны нулю:

DECLARE 
v_notnull varchar2(30):='this string is never null'; 
v_input varchar2(30):=''; 
BEGIN 
    IF (trim(v_input) is null and trim(v_notnull) is not null) 
     or (trim(v_input) is not null and trim(v_notnull) is null) 
     or trim(v_input) != trim(v_notnull) THEN 
     dbms_output.put_line('the strings do NOT match'); 
    ELSE 
     dbms_output.put_line('the strings DO match'); 
    END IF; 
END; 
/

the strings do NOT match 


PL/SQL procedure successfully completed. 

Я добавил отсутствующие размеры varchar2; предположительно вы основывали это на процедуре, в которой принимались аргументы, не запуская то, что вы отправляли автономно ...

3

''NULL in oracle. Таким образом, любое сравнение с null всегда будет приводить к ложному.

Демо:

SQL> DECLARE 
    2 v_notnull varchar2(1000):='this string is never null'; 
    3 v_input varchar2(1000):=''; 
    4 BEGIN 
    5  IF v_input is null THEN 
    6   dbms_output.put_line('v_input is null'); -- should print because v_input is actually null 
    7  END IF; 
    8 
    9  IF trim(v_input) = trim(v_notnull) THEN  -- always false because of null 
10   dbms_output.put_line('the strings do NOT match'); 
11  ELSE 
12   dbms_output.put_line('the strings DO match'); -- so should print this 
13  END IF; 
14 END; 
15/
v_input is null   -- verified 
the strings DO match  -- verified 

PL/SQL procedure successfully completed. 

SQL> 
0

Часто вы только заботитесь матч значения, в этом случае нулевые значения не делают ли никакой разницы:

declare 
    v_notnull varchar2(50) := 'this string is never null'; 
    v_input varchar2(50) := ''; 
begin 
    if trim(v_input) = trim(v_notnull) then 
     dbms_output.put_line('the strings DO match'); 
    else 
     dbms_output.put_line('the strings do NOT match'); 
    end if; 
end; 

В некоторых случаях вы можете упростить сравнение обнуляемого значений с использованием coalesce() или nvl() выражение:

if nvl(v_yesno,'N') <> 'Y' then ... 

Вы можете быть в состоянии использовать фиктивное значение сравнения (хотя, конечно, существует риск того, что он будет соответствовать фактической стоимости, в зависимости от ситуации):

if nvl(somevalue, chr(0)) <> nvl(othervalue, chr(0)) then ... 

Кстати, вы можете различать null и '', скопировав значение в переменную char, так как '' вызовет ее бесполезное поведение пустого заполнения. Я не могу думать о ситуации, когда это было бы полезно, но просто для удовольствия:

declare 
    v1 varchar2(1) := null; 
    v2 varchar2(1) := ''; 

    c char(1); 
begin 
    c := v1; 
    if v1 is null and c is not null then 
     dbms_output.put_line('v1 = '''''); 
    elsif c is null then 
     dbms_output.put_line('v1 is null'); 
    end if; 

    c := v2; 
    if v2 is null and c is not null then 
     dbms_output.put_line('v2 = '''''); 
    elsif c is null then 
     dbms_output.put_line('v2 is null'); 
    end if; 

end; 

Выход:

v1 is null 
v2 = '' 

 Смежные вопросы

  • Нет связанных вопросов^_^