Хочу функцию в Oracle для удаления дубликатов из строки

Рейтинг: 1Ответов: 2Опубликовано: 07.02.2023

Есть строки с IP адресами, например Слева то есть сейчас, справа то хочу получить на выходе

192.168.0.2 >> 192.168.0.2
192.168.0.120;192.168.0.120 >> 192.168.0.120
192.168.0.160;192.168.0.160;192.168.0.160 >> 192.168.0.160
192.168.0.15;142.15.23.10;192.168.0.15 >> 192.168.0.15;142.15.23.10

и т.д.

Написал начало функции и понятия не имею как загнать части строки в массив и удалить дубликаты. На PHP я уже давно бы это сделал, а в Oracle темный лес

CREATE OR REPLACE FUNCTION distinct_string(
    string$ in VARCHAR2,
    separator$ in VARCHAR2
)
RETURN VARCHAR2 IS
BEGIN
    IF string$ IS NULL
        THEN RETURN string$;
    END IF;
    
    IF INSTR(string$, separator$) = 0
        THEN RETURN string$;
    END IF;
    
    FOR i IN 1 .. regexp_count(string$, separator$) LOOP
        dbms_output.put_line(i);
    END LOOP;
    
    RETURN 'String without dublicates';
END;

Ответы

▲ 1Принят

как то так у меня получилось

CREATE OR REPLACE FUNCTION distinct_string(string$    IN VARCHAR2,
                                           separator$ IN VARCHAR2)
  RETURN VARCHAR2 IS
  TYPE t_numbers IS TABLE OF NUMBER(20);
  TYPE t_strings IS TABLE OF VARCHAR2(250);
  numbers_coll t_numbers := t_numbers();
  strings_coll t_strings := t_strings();
  input_string VARCHAR2(250);
  FnReturn     VARCHAR2(250);
BEGIN
  IF string$ IS NULL OR INSTR(string$, separator$) = 0 THEN
    RETURN string$;
  END IF;
  
  IF SUBSTR(string$, -1) = separator$ THEN
    input_string := SUBSTR(string$, 1, LENGTH(string$) - 1);
  ELSE
    input_string := string$;
  END IF;

  numbers_coll.extend();
  numbers_coll(numbers_coll.last) := 0;

  FOR i IN 1 .. LENGTH(input_string) LOOP
    IF SUBSTR(input_string, i, 1) = ';' THEN
      numbers_coll.extend();
      numbers_coll(numbers_coll.last) := i;
    END IF;
  END LOOP;

  IF numbers_coll IS NOT empty THEN
    FOR i IN numbers_coll.first .. numbers_coll.last LOOP
      strings_coll.extend();
      IF i = numbers_coll.last THEN
        strings_coll(strings_coll.last) := SUBSTR(input_string,
                                                  numbers_coll(i) + 1);
      ELSE
        strings_coll(strings_coll.last) := SUBSTR(input_string,
                                                  numbers_coll(i) + 1,
                                                  numbers_coll(i + 1) -
                                                  numbers_coll(i) - 1);
      END IF;
    END LOOP;
  END IF;

  strings_coll := SET(strings_coll);

  FnReturn := '';

  IF strings_coll IS NOT empty THEN
    FOR i IN strings_coll.first .. strings_coll.last LOOP
      FnReturn := FnReturn || strings_coll(i) || separator$;
    END LOOP;
  END IF;

  IF SUBSTR(FnReturn, -1) = separator$ THEN
    FnReturn := SUBSTR(FnReturn, 1, LENGTH(FnReturn) - 1);
  END IF;

  RETURN FnReturn;
END;
▲ 0

Если есть apex:

select distinct
    column_value
FROM TABLE(apex_string.split('192.168.0.15;142.15.23.10;192.168.0.15', ';'));