Khắc phục lỗi ORA-01830 khi đồng bộ dữ liệu tăng dần trong Oracle

Trong quá trình thực hiện đồng bộ hóa dữ liệu tăng dần (incremental synchronization) giữa bảng nguồn mdm_organization và bảng đích mdm_zn_organization, lỗi ORA-01830: datetime format picture ends before converting entire input string thường xảy ra do sự không nhất quán giữa định dạng chuỗi ký tự và kiểu dữ liệu ngày tháng (Date) của Oracle.

Nguyên nhân và cách xử lý

Lỗi này xuất hiện khi bạn cố gắng so sánh hoặc chuyển đổi kiểu dữ liệu mà độ dài của chuỗi đầu vào (thường chứa cả phần mili giây) vượt quá định dạng 'yyyy-mm-dd hh24:mi:ss' đã chỉ định.

Để giải quyết, bạn cần lấy giá trị thời gian sửa đổi mới nhất từ bảng đích làm mốc so sánh cho bảng nguồn. Sử dụng substr để cắt bỏ phần thừa (như mili giây) trước khi thực hiện ép kiểu:

SELECT * FROM mdm_organization src 
WHERE src.org_last_modified_time > TO_DATE(
    SUBSTR((SELECT NVL(MAX(org_last_modified_time), TO_DATE('1900', 'yyyy')) FROM mdm_zn_organization), 1, 19), 
    'yyyy-mm-dd hh24:mi:ss'
);

Triển khai đồng bộ bằng MyBatis

Sau khi truy vấn được các bản ghi thay đổi, tiến hành xử lý logic trong mã nguồn Java. Dưới đây là cách tạo định danh duy nhất và đồng bộ dữ liệu:

List<Map<String, Object>> dataList = orgMapper.findNewChanges();
for (Map<String, Object> entry : dataList) {
    String uuid = UUID.randomUUID().toString().replace("-", "");
    entry.put("NEW_ID", uuid);
    orgMapper.upsertOrg(entry);
}

Tại lớp ánh xạ (Mapper) MyBatis, sử dụng lệnh MERGE INTO để xử lý logic "Upsert" (cập nhật nếu tồn tại, chèn mới nếu chưa có):

<insert id="upsertOrg" parameterType="map">
    MERGE INTO mdm_zn_organization target
    USING (SELECT #{NEW_ID} AS ID, #{CODE} AS ORG_CODE, #{MOD_TIME} AS MOD_TIME FROM DUAL) src
    ON (target.CODE = src.ORG_CODE)
    WHEN MATCHED THEN
        UPDATE SET target.ORG_LAST_MODIFIED_TIME = src.MOD_TIME
    WHEN NOT MATCHED THEN
        INSERT (ID, CODE, ORG_LAST_MODIFIED_TIME)
        VALUES (src.ID, src.ORG_CODE, src.MOD_TIME)
</insert>

Tự động hóa quy trình

Để hoàn tất giải pháp đồng bộ định kỳ, bạn có thể cấu hình Spring Quartz Task để thực thi phương thức đồng bộ nêu trên theo khoảng thời gian mong muốn (ví dụ: mỗi 5 phút/lần). Phương pháp này đảm bảo tính toàn vẹn dữ liệu và tối ưu hiệu suất bằng cách chỉ xử lý các dòng dữ liệu mới thay vì đồng bộ toàn bộ bảng.

Thẻ: Oracle sql mybatis Spring-Quartz Data-Synchronization

Đăng vào ngày 2 tháng 7 lúc 17:22