Сравнение переменных типа данных PL/SQL Raw

Можно ли сравнивать переменные необработанных типов данных? Я работаю с XMLDOM.DomNodes, который представляет собой записи с одним полем:

TYPE DOMNode IS RECORD (id RAW(12));

Итак, у меня есть два узла, могу ли я сравнить их по полям идентификатора? Я попробовал несколько образцов, и на первый взгляд кажется, что это работает:

  FUNCTION findParentNode(p_node IN xmldom.domnode) RETURN PLS_INTEGER
  AS
      nRetVal               PLS_INTEGER;
  BEGIN
     FOR i IN ParentNodes.First .. ParentNodes.Last
     LOOP 
         IF ParentNodes(i).id = p_node.id THEN               
            nRetVal := i;
            EXIT;
         END IF;         
     END LOOP;

     RETURN nRetVal;
  END;

но одна вещь в документации Oracle меня беспокоит: Необработанные данные похожи на данные VARCHAR2 , за исключением того, что PL/SQL не интерпретирует необработанные данные Что это значит? Если pl/sql не интерпретирует raw, может ли он сравниваться?


person Andrey Khataev    schedule 10.02.2012    source источник


Ответы (3)


Вы можете использовать оператор =, если хотите увидеть, имеют ли две переменные RAW одинаковые значения.

SQL> DECLARE
  2     a RAW(255) := utl_raw.cast_to_raw('abcdef');
  3     b RAW(50) := utl_raw.cast_to_raw('abcdef');
  4  BEGIN
  5     IF a = b THEN
  6        dbms_output.put_line('a = b');
  7     ELSE
  8        dbms_output.put_line('a != b');
  9     END IF;
 10  END;
 11  /
a = b

Когда в документации говорится, что RAW похож на VARCHAR2, но не интерпретируется, это означает, что вы можете воздействовать, хранить и даже сравнивать переменные RAW так же, как и VARCHAR2, но двоичное значение никогда не сопоставляется с набором символов.

С другой стороны, переменные VARCHAR2 могут быть преобразованы из-за несоответствия между наборами символов базы данных и клиента.

RAW — это строка байтов, а не строка символов.

person Vincent Malgrat    schedule 10.02.2012

Я не уверен, что документация подразумевает под этим, но для сравнения двух необработанных данных я бы использовал функцию UTL_RAW.COMPARE. Подробнее см. здесь.

UTL_RAW.COMPARE сравнивает одно необработанное значение с другим необработанным значением. Если они идентичны, то UTL_RAW.COMPARE возвращает ноль. Если они не идентичны, то COMPARE возвращает позицию первого несовпадающего байта. Если входные значения имеют разную длину, то более короткое входное значение дополняется справа указанным значением.

person John Doyle    schedule 10.02.2012
comment
Мне кажется, что оператор = тоже умеет сравнивать сырки, но если что-то пойдет не так, то воспользуюсь вашим советом. Спасибо - person Andrey Khataev; 10.02.2012

Вы должны использовать:

IF(NVL(a,'X') != NVL(b,'Y')) THEN
.....

Oracle не сравнивает пустые/пустые строки правильно, поэтому вы должны указать, что если это пустое или пустое значение, то придать ему другое значение, чем другое.

person Israel Margulies    schedule 14.02.2013