I'd like to delete the existing data before insert based on ids. So if there are ids in incoming file then existing ids should be deleted, and then data should be entered. Something like this:
DATABASE TABLE BEFORE:
--------------------------------
| ID | DATA |
--------------------------------
| 1 | This is data for ID 1 |
| 2 | This is data for ID 2 |
| 3 | This is data for ID 3 |
--------------------------------
INCOMING FILE:
-----------------------------------------
| ID | DATA |
-----------------------------------------
| 1 | This is new data for ID 1 |
| 2 | This is new data for ID 2 |
| 4 | This is new data for ID 4 |
| 1 | This is also new data for ID 1 |
-----------------------------------------
DATABASE TABLE AFTER:
-----------------------------------------
| ID | DATA |
-----------------------------------------
| 1 | This is new data for ID 1 |
| 2 | This is new data for ID 2 |
| 4 | This is new data for ID 4 |
| 1 | This is also new data for ID 1 |
| 3 | This is data for ID 3 |
-----------------------------------------
This is my procedure.
CREATE OR REPLACE PROCEDURE absence_records_in AS
l_v_file UTL_FILE.file_type;
l_filename VARCHAR2(128);
l_buffer VARCHAR2(4096);
l_start BINARY_INTEGER := 1;
l_pos BINARY_INTEGER;
TYPE typ_cols IS TABLE OF VARCHAR2(4096) INDEX BY BINARY_INTEGER;
tbl_cols typ_cols;
l_col_no BINARY_INTEGER;
l_count BINARY_INTEGER := 0;
BEGIN
l_filename := 'records.csv';
l_v_file := UTL_FILE.fopen('DIR_FENIX_IN', l_filename, 'R');
UTL_FILE.get_line(l_v_file, l_buffer);
LOOP
BEGIN
UTL_FILE.get_line(l_v_file, l_buffer);
IF l_buffer IS NULL THEN
EXIT;
END IF;
l_col_no := 1;
l_start := 1;
WHILE INSTR(l_buffer, ';', 1, l_col_no) !=0
LOOP
l_pos := INSTR(l_buffer, ';', 1, l_col_no);
tbl_cols(l_col_no) := SUBSTR( l_buffer, l_start, l_pos - l_start);
l_start := l_pos + 1;
l_col_no := l_col_no + 1;
END LOOP;
l_start := l_pos + 1;
tbl_cols(l_col_no) := SUBSTR( l_buffer, l_start);
DELETE FROM absence_records WHERE id = tbl_cols(1)
LOG ERRORS INTO in_errors('File: '||l_filename||' => delete operation') REJECT LIMIT UNLIMITED;
l_count := l_count + 1;
EXCEPTION WHEN NO_DATA_FOUND THEN
EXIT;
END;
BEGIN
UTL_FILE.get_line(l_v_file, l_buffer);
IF l_buffer IS NULL THEN
EXIT;
END IF;
l_col_no := 1;
l_start := 1;
WHILE INSTR(l_buffer, ';', 1, l_col_no) !=0
LOOP
l_pos := INSTR(l_buffer, ';', 1, l_col_no);
tbl_cols(l_col_no) := SUBSTR( l_buffer, l_start, l_pos - l_start);
l_start := l_pos + 1;
l_col_no := l_col_no + 1;
END LOOP;
l_start := l_pos + 1;
tbl_cols(l_col_no) := SUBSTR( l_buffer, l_start);
INSERT INTO absence_records (id, data)
VALUES (tbl_cols(1), tbl_cols(2))
LOG ERRORS INTO in_errors('File: '||l_filename|| ' => insert operation') REJECT LIMIT UNLIMITED;
l_count := l_count + 1;
EXCEPTION WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
UTL_FILE.fclose(l_v_file);
END absence_records_in;
So in short, I need to start one loop that will delete only data which is in comparison, and then another loop that will insert the data. Any ideas? Thanks in advance :-)