CADENAS DE CARACTERES A REGISTROS
esto hice en MySQL como SP y esto es invocado por un WS,recibe la data y procesa como lo vez.
Pasalo a oracle y puedes poner en un SP o Trigger
DECLARE as_cadena VARCHAR(65500) := 'A,B,C,D,E;A,B,C,,E;A,,,D,E;'
DECLARE ls_valores VARCHAR(80);
DECLARE li_posini NUMERIC DEFAULT 1;
DECLARE li_posfin NUMERIC DEFAULT 1;
DECLARE li_elemen INTEGER;
DECLARE ls_bloque CHAR(1);
DECLARE ls_id VARCHAR(10);
DECLARE ls_nombres VARCHAR(25);
DECLARE ls_paterno VARCHAR(25);
DECLARE ls_materno VARCHAR(25);
DECLARE li_existe INTEGER;
WHILE li_posfin > 0 DO
SET li_posfin = LOCATE(',', as_cadena, li_posini);
SET ls_valores = SUBSTRING(as_cadena, li_posini, li_posfin - li_posini);
IF ls_valores = ';' THEN
SET ls_bloque = ls_valores;
SET li_elemen = 1;
ELSE
SET li_elemen = li_elemen + 1;
END IF;
IF li_elemen = 2 THEN
SET ls_id = RIGHT(CONCAT('0000000000', ls_valores), 10);
END IF;
IF li_elemen = 3 THEN
SET ls_nombres = ls_valores;
END IF;
IF li_elemen = 4 THEN
SET ls_paterno = ls_valores;
END IF;
IF li_elemen = 5 THEN -- 1...5 es por la cantidad de datos ('A,B,C,D,E;') por ello se debe completar la catidad de separadores ('A,,,D,E;')
SET ls_materno = ls_valores;
END IF;
IF li_elemen = 5 AND ls_bloque = ';' THEN
SET li_existe = (SELECT COUNT(id) FROM mi_tabla WHERE id = ls_id);
IF li_existe = 0 THEN
INSERT INTO mi_tabla(id, Nombres, ApellidoPaterno, ApellidoMaterno)
VALUES (ls_id, ls_nombres, ls_paterno, ls_materno);
ELSE
UPDATE mi_tabla SET Nombres = ls_nombres, ApellidoPaterno = ls_paterno, ApellidoMaterno = ls_materno WHERE id = ls_id;
END IF;
END IF;
SET li_posini = li_posfin + 1;
END WHILE;
espero te sirva.
saludos.