對於你的情況,我建議使用觸發器,並使汽車的操作。 以下觸發條件會隨時插入一個新行到您的EXTRACT表(條件1/2)或從中刪除(條件3),並且將檢查:
當插入到EXTRACT:
if circuitId = circuitId and checksum = checksum(*)
then do nothing
if circuitId = circuiId and checksum <> checksum(*)
then insert new row and set end_date of old row.
當從EXTRACT正在刪除:
if rows exists in archive but not in staging
then change delete_flag to 1
觸發您的條件:
CREATE OR REPLACE TRIGGER archiver
AFTER INSERT OR DELETE
ON EXTRACT.F1_Circuits
REFERENCES OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
v_extr_new_row VARCHAR2 (500); --- for storing new inserting row data
v_extr_row_checksum RAW(500); --- for storing new row as RAW
v_encrypted_raw RAW(2048); --- encrypted to md5 data
v_arch_cir_id NUMBER (11) := 0; --- circuitId from ARCHIVE table
v_arch_checksum VARCHAR2 (32) := '0'; --- checksum from ARCHIVE table
v_arch_last_chsum NUMBER (3); --- for finding the latest data by checksum in ARCH table
v_arch_start_date TIMESTAMP; --- for finding the latest data by start_date in ARCH table
BEGIN
IF INSERTING THEN
--- taking the inserting data into the variable for further converting to md5
v_extr_new_row := :NEW."circuitId" || ',' || :NEW."circuitRef" || ',' || :NEW."name" || ',' ||
:NEW."location" || ',' || :NEW."country" || ',' || :NEW."lat" || ',' ||
:NEW."lng" || ',' || :NEW."alt" || ',' || :NEW."url";
--- converting the inserting data to hash_md5, checksum
v_extr_row_checksum := utl_raw.cast_to_raw(v_extr_new_row);
v_encrypted_raw := dbms_crypto.hash(v_extr_row_checksum, 2);
--- taking the latest row from the ARCH table for changing the Updating the END_DATE;
SELECT START_TIMESTAMP, r_last_chsum, CHECKSUM, circuitId
INTO v_arch_start_date, v_arch_last_chsum, v_arch_checksum, v_arch_cir_id
FROM
(SELECT START_TIMESTAMP, ROW_NUMBER()
OVER (PARTITION BY arch_in.circuitId ORDER BY arch_in.START_TIMESTAMP DESC) r_last_chsum,
CIRCUITID, CHECKSUM
FROM ARCHIVE.F1_CIRCUITS arch_in
WHERE arch_in.circuitId = :NEW."circuitId")
WHERE r_last_chsum = 1;
---- checking whether the data already exist in the ARCH table
IF (v_arch_cir_id = :NEW."circuitId" AND v_arch_checksum <> v_encrypted_raw)
THEN
---- Update end_date for old row
UPDATE ARCHIVE.F1_CIRCUITS arch
SET arch.END_TIMESTAMP = CURRENT_TIMESTAMP
WHERE arch.circuitId = :NEW."circuitId"
AND arch.CHECKSUM = v_arch_checksum
AND arch.START_TIMESTAMP = v_arch_start_date;
--- inserting the new data into ARCH table
INSERT INTO ARCHIVE.F1_CIRCUITS
(CIRCUITID, CIRCUITREF, NAME, LOCATION, COUNTRY, LAT, LNG, ALT, URL, START_TIMESTAMP, END_TIMESTAMP, CHECKSUM,
STATUS, DELETE_FLAG)
VALUES (:NEW."circuitId", :NEW."circuitRef", :NEW."name", :NEW."location", :NEW."country",
:NEW."lat", :NEW."lng", :NEW."alt", :NEW."url", CURRENT_TIMESTAMP, NULL, v_encrypted_raw, 'C', to_number (0));
---- else if they are EQUAL then DO NOTHING, but if you need you can do;)
ELSIF (v_arch_cir_id = :NEW."circuitId" AND v_arch_checksum = v_encrypted_raw)
THEN
dbms_output.put_line ('Do Nothing!');
/* INSERT INTO ikrom.f1_circuits_arch ---- ARCHIVE.F1_CIRCUITS
(CIRCUITID, CIRCUITREF, NAME, LOCATION, COUNTRY, LAT, LNG, ALT, URL, START_TIMESTAMP, END_TIMESTAMP, CHECKSUM,
STATUS, DELETE_FLAG)
VALUES (:NEW."circuitId", :NEW."circuitRef", :NEW."name", :NEW."location", :NEW."country",
:NEW."lat", :NEW."lng", :NEW."alt", :NEW."url", CURRENT_TIMESTAMP, NULL, v_encrypted_raw, 'C', to_number (0));*/
END IF;
END IF;
IF DELETING THEN
--- taking the inserting data into the variable for further converting to md5
v_extr_new_row := :OLD."circuitId" || ',' || :OLD."circuitRef" || ',' || :OLD."name" || ',' ||
:OLD."location" || ',' || :OLD."country" || ',' || :OLD."lat" || ',' ||
:OLD."lng" || ',' || :OLD."alt" || ',' || :OLD."url";
--- converting the inserting data to hash_md5, checksum
v_extr_row_checksum := utl_raw.cast_to_raw(v_extr_new_row);
v_encrypted_raw := dbms_crypto.hash(v_extr_row_checksum, 2);
--- taking the latest row from the ARCH table for changing the Updating the END_DATE;
SELECT START_TIMESTAMP, r_last_chsum, CHECKSUM, circuitId
INTO v_arch_start_date, v_arch_last_chsum, v_arch_checksum, v_arch_cir_id
FROM
(SELECT START_TIMESTAMP, ROW_NUMBER()
OVER (PARTITION BY arch_in.circuitId ORDER BY arch_in.START_TIMESTAMP DESC) r_last_chsum,
CIRCUITID, CHECKSUM
FROM ARCHIVE.F1_CIRCUITS arch_in
WHERE arch_in.circuitId = :OLD."circuitId")
WHERE r_last_chsum = 1;
---- checking whether the data already exist in the ARCH table
IF (v_arch_cir_id = :OLD."circuitId")
THEN
---- Update end_date for old row
UPDATE ARCHIVE.F1_CIRCUITS arch
SET arch.DELETE_FLAG = 1
WHERE arch.circuitId = :OLD."circuitId"
AND arch.DELETE_FLAG = 0;
END IF;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
---- if no data found in ARCH table by SELECTING in INSERTING process then just INSERT the new row
INSERT INTO ARCHIVE.F1_CIRCUITS
(CIRCUITID, CIRCUITREF, NAME, LOCATION, COUNTRY, LAT, LNG, ALT, URL, START_TIMESTAMP, END_TIMESTAMP, CHECKSUM,
STATUS, DELETE_FLAG)
VALUES (:NEW."circuitId", :NEW."circuitRef", :NEW."name", :NEW."location", :NEW."country",
:NEW."lat", :NEW."lng", :NEW."alt", :NEW."url", CURRENT_TIMESTAMP, NULL, v_encrypted_raw, 'C', to_number (0));
END;
重要說明:從Extract表中刪除時,ARCHIVE中具有相同circuitId的所有行都將被更新; 也爲dbms_crypto授予觸發器運行用戶的執行權限;
什麼是EXTRACT表? –
woops提取物是分期。把所有東西都改爲EXTRACT而不是升級 –