Как найти дубликаты вне зависимости от регистра из коллекции оракулов, используя оператор SET - PullRequest
0 голосов
/ 27 апреля 2019

Я знал, что с помощью оператора SET мы можем игнорировать или находить дубликаты значений из коллекции pl sql.Насколько мне известно, оператор SET найдет дубликаты только с одинаковым регистром (все значения либо в нижнем, либо в верхнем регистре).Было бы здорово, если бы кто-нибудь мог объяснить, как найти дубликаты, независимо от регистра.

Большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 27 апреля 2019

Это то, что у вас есть сейчас:

SQL> declare
  2    type lt is table of varchar2(10);
  3    l_col lt := lt ('A', 'A', 'B', 'a', 'b');
  4    l_set lt;
  5  begin
  6    dbms_output.put_line('Original -----');
  7    for i in l_col.first .. l_col.last loop
  8      dbms_output.put_line(l_col(i));
  9    end loop;
 10
 11    dbms_output.put_line('Set ----------');
 12    l_set := set(l_col);
 13    for i in l_set.first .. l_set.last loop
 14      dbms_output.put_line(l_set(i));
 15    end loop;
 16  end;
 17  /
Original -----
A
A
B
a
b
Set ----------
A       --> this "A" is "duplicate" of ...
B
a       --> ... this "a"
b

PL/SQL procedure successfully completed.

SQL>

Один из вариантов (избавиться от этих дубликатов) - переключиться на регистр без учета регистра :

SQL> alter session set nls_comp = linguistic;

Session altered.

SQL> alter session set nls_sort = binary_ai;

Session altered.

Теперь, запустив тот же код PL / SQL, вы получите:

SQL> declare
  2    type lt is table of varchar2(10);
  3    l_col lt := lt ('A', 'A', 'B', 'a', 'b');
  4    l_set lt;
  5  begin
  6    dbms_output.put_line('Original -----');
  7    for i in l_col.first .. l_col.last loop
  8      dbms_output.put_line(l_col(i));
  9    end loop;
 10
 11    dbms_output.put_line('Set ----------');
 12    l_set := set(l_col);
 13    for i in l_set.first .. l_set.last loop
 14      dbms_output.put_line(l_set(i));
 15    end loop;
 16  end;
 17  /
Original -----
A
A
B
a
b
Set ----------
A               --> no more duplicates
B

PL/SQL procedure successfully completed.

SQL>

[EDIT]

Что касается вашего комментария о невозможности изменить сеанс внутри хранимой процедуры (пакета, чего угодно), хорошо - вы можете сделать это, используя динамический SQL.Вот демонстрация (примечания 6 и 7):

SQL> declare
  2    type lt is table of varchar2(10);
  3    l_col lt := lt ('A', 'A', 'B', 'a', 'b');
  4    l_set lt;
  5  begin
  6    execute immediate 'alter session set nls_comp = linguistic';
  7    execute immediate 'alter session set nls_sort = binary_ai';
  8
  9    dbms_output.put_line('Original -----');
 10    for i in l_col.first .. l_col.last loop
 11      dbms_output.put_line(l_col(i));
 12    end loop;
 13
 14    dbms_output.put_line('Set ----------');
 15    l_set := set(l_col);
 16    for i in l_set.first .. l_set.last loop
 17      dbms_output.put_line(l_set(i));
 18    end loop;
 19  end;
 20  /
Original -----
A
A
B
a
b
Set ----------
A
B

PL/SQL procedure successfully completed.

SQL>

Если вы не хотите этого делать, я полагаю, вам придется «экспортировать» содержимое коллекции в таблицу (может быть дажеглобальная / частная временная таблица, в зависимости от используемой версии базы данных), исключите дубликаты и заполните коллекцию только различными значениями.

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