Найти конкретный varchar в Oracle Nested Table - PullRequest
8 голосов
/ 14 июня 2011

Я новичок в PL-SQL, и пытаюсь найти четкую документацию по операциям с вложенными таблицами. Пожалуйста, исправьте любые неправильно используемые термины и т. Д.

У меня есть вложенный тип таблицы, который я использую в качестве параметров для хранимой процедуры.

CREATE OR REPLACE TYPE "STRARRAY" AS TABLE OF VARCHAR2 (255)

В моей хранимой процедуре таблица инициализируется и заполняется. Скажем, у меня есть переменная VARCHAR2, и я хочу знать true или false, если этот varchar существует во вложенной таблице.

Я пытался

strarray.exists('somevarchar')

но я получаю ORA-6502

Есть ли более простой способ сделать это, кроме итерации?

FOR i IN strarray.FIRST..strarray.LAST
    LOOP
        IF strarray(i) = value THEN
            return 1;--found
        END IF;
    END LOOP;

Ответы [ 4 ]

8 голосов
/ 15 июня 2011

Для проверки одного значения я предпочитаю оператор "member" .

zep@dev> declare
      2      enames     strarray;
      3      wordToFind varchar2(255) := 'King';
      4  begin
      5      select emp.last_name bulk collect
      6      into   enames
      7      from   employees emp;
      8      if wordToFind member of enames then
      9          dbms_output.put_line('Found King');
     10      end if;
     11  end;
     12  /

Found King

PL/SQL procedure successfully completed

zep@dev> 
5 голосов
/ 14 июня 2011

Вы можете использовать оператор MULTISET INTERSECT, чтобы определить, существует ли интересующая вас строка в коллекции. Например

declare
  l_enames strarray;
  l_interesting_enames strarray := new strarray( 'KING' );
begin
  select ename
    bulk collect into l_enames
    from emp;
  if( l_interesting_enames = l_interesting_enames MULTISET INTERSECT l_enames )
  then
    dbms_output.put_line( 'Found King' );
  end if;
end;

выведет «Found King», если строка «KING» является элементом коллекции l_enames.

3 голосов
/ 15 июня 2011

Когда вложенная таблица объявляется как тип уровня схемы, как вы это сделали, ее можно использовать в любом запросе SQL в качестве таблицы.Таким образом, вы можете написать простую функцию, например, так:

CREATE OR REPLACE FUNCTION exists_in( str VARCHAR2, tab stararray)
  RETURN BOOLEAN
  AS
    c  INTEGER;
  BEGIN
    SELECT COUNT(*)
      INTO c
      FROM TABLE(CAST(tab AS strarray))
      WHERE column_value = str;
    RETURN (c > 0);
  END exists_in;
3 голосов
/ 15 июня 2011

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

Однако вы можете захотеть смотреть на ассоциативные массивы, а не на коллекции, если вы хотите сослаться на элемент массива по строковому индексу. Это будет выглядеть так:

DECLARE
  TYPE assocArray IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
  myArray assocArray;
BEGIN

  myArray('foo') := 'bar';

  IF myArray.exists('baz') THEN
    dbms_output.put_line(myArray('baz'));

  ELSIF myArray.exists('foo') THEN
    dbms_output.put_line(myArray('foo'));

  END IF;

END;

По сути, если значения вашего массива различны, вы можете создать парные массивы, ссылающиеся друг на друга, например, arr('b') := 'a'; arr('a') := 'b';

Эта техника может помочь вам легко найти любой элемент и его индекс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...