Как изменить строку CLOB, содержащую определенное значение, используя триггер с PL SQL? - PullRequest
0 голосов
/ 09 апреля 2020

Я борюсь с проблемой, связанной с CLOB. Я хотел бы создать триггер (после обновления), который обновляет столбец таблицы, которая является CLOB. Этот CLOB содержит строки в этой форме:

foo|132|65|12/08/2016|18395|
bar|132|54|15/08/2014|32434343|

Я хотел бы изменить CLOB таким образом, чтобы строка, начинающаяся с "foo", имела значение "18395", деленное на 1000. Строка будет выглядеть как

foo|132|65|12/08/2016|18.395|

Есть ли быстрый способ изменить мой CLOB?

Спасибо за вашу помощь.

РЕДАКТИРОВАТЬ: я нашел способ изменить строку CLOB, что мне нужно сделать, это просто изменить CLOB, чтобы заменить

foo|132|65|12/08/2016|18395|

на

foo|132|65|12/08/2016|18.395|

1 Ответ

0 голосов
/ 09 апреля 2020

Это довольно долго, но эффективно. Сначала создайте тип:

create or replace TYPE  "array_str" AS VARRAY(10) OF VARCHAR(256);

Затем создайте функцию, которая будет возвращать массив на основе разделителя:

FUNCTION string_to_array (
    string_delimited   IN   VARCHAR2,
    delimiter          IN   VARCHAR2 DEFAULT ','
) RETURN array_str IS
    pls_idx        PLS_INTEGER;
    split_string   array_str := array_str();
    pls_del_len    PLS_INTEGER := length(delimiter);
BEGIN
    IF string_delimited IS NOT NULL THEN
        LOOP
    -- search for delimiter string
            pls_idx := instr(l_string_delimited, delimiter);
    -- increase the size of array
            split_string.extend;

    -- check last search of delimiter is success
            IF pls_idx = 0 THEN
                split_string(l_split_string.count) := substr(l_string_delimited, 1);
            ELSE
                split_string(l_split_string.count) := substr(l_string_delimited, 1, pls_idx - 1);
            END IF;

    -- exit from loop when last string

            EXIT WHEN nvl(l_pls_idx, 0) = 0;
            string_delimited := substr(l_string_delimited, pls_idx + pls_del_len);
        END LOOP;
    END IF;

    RETURN split_string;
END string_to_array;

Затем создайте триггер:

CREATE OR REPLACE TRIGGER your_trigger AFTER
    UPDATE ON table_name
    FOR EACH ROW
DECLARE
    clob_array   array_str;
    clob_str     CLOB := '';
BEGIN
    clob_array := string_to_array(:new.new_clob, '|');
    IF ( clob_array(1) = 'foo' ) THEN
        clob_array(5) := to_number(clob_array(5) / 1000);
    END IF;

    FOR i IN 1..clob_array.count - 1 LOOP clob_str := clob_str
                                                      || to_char(clob_array(i))
                                                      || '|';
    END LOOP;

    -- do something with clob_str

END;
...