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.