5

Tôi chưa bao giờ sử dụng Liquibase trước đây và không thể tìm ra cách giải quyết vấn đề này. Dự án tôi vừa mới tham gia là một bản làm lại của một dự án cũ, vì vậy chúng tôi phải gắn bó với một cơ sở dữ liệu cũ, có lược đồ được thiết kế khủng khiếp. Cơ sở dữ liệu không sử dụng các ràng buộc khóa ngoài, vì vậy vẫn còn các mục trỏ đến một mục không tồn tại nữa. Trong trường hợp của tôi, đó là một bác sĩ có một tài khoản ngân hàng tại một ngân hàng không tồn tại trong cơ sở dữ liệu. Cách nhóm của tôi xử lý các vấn đề này cho đến nay đã ghi đè ID với NULL. Vì vậy, về cơ bản những gì tôi đang cố gắng làm là đặt tất cả các ID tài khoản ngân hàng thành NULL, khi ngân hàng không tồn tại. Mã SQL mà tôi đã thực hiện để thực hiện tác vụ này như sau:Cập nhật các hàng trong Liquibase với câu lệnh WHERE

UPDATE DOCTOR SET FK_BANKID = NULL WHERE FK_BANKID NOT IN (SELECT ID FROM BANK); 

Tôi đã được thông báo rằng tích hợp vào bộ thay đổi Liquibase của chúng tôi, nhưng tôi không thể tìm ra cách thực hiện. Đây là những gì tôi đã thực hiện cho đến thời điểm này:

<?xml version="1.0" encoding="UTF-8"?> 

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
             http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> 
    <changeSet id="remove_fk_bankid" author="v7"> 
     <update tableName="DOCTOR"> 
      <column name="FK_BANKID" value="NULL" /> 
      <where>FK_BANKID NOT IN (SELECT ID FROM BANK)</where> 
     </update> 
    </changeSet> 
</databaseChangeLog> 

Bản cập nhật Liquibase chạy không có lỗi, nhưng khi tôi nhìn vào cơ sở dữ liệu sau đó, không có gì thay đổi. Có ai có bất kỳ con trỏ cho tôi làm thế nào để giải quyết vấn đề này?

+0

Oh và bằng cách này, chúng tôi đang sử dụng một cơ sở dữ liệu Oracle 10g nếu giúp. – David

Trả lời

7

Cuối cùng tôi đã tìm ra vấn đề là gì. Thực sự không có vấn đề gì với bản thân changeset. Khi Liquibase cập nhật cơ sở dữ liệu, nó ghi lại tất cả các thay đổi trong cơ sở dữ liệu, để các thay đổi đã được thực thi sẽ không thực hiện lại. Liquibase lưu một hàm băm của nội dung của changeset, do đó các thay đổi đã được thay đổi sẽ được thực hiện lại. Vấn đề thực tế là cơ sở dữ liệu đã được làm sạch khi tôi lần đầu tiên thực hiện các changeset, bởi vì tôi đã làm nó bằng tay bằng cách sử dụng lệnh SQL sau đây: UPDATE DOCTOR SET FK_BANKID = NULL WHERE FK_BANKID NOT IN (SELECT ID FROM BANK);. Sau đó tôi thay đổi một hàng bác sĩ và thiết lập ID ngân hàng cho một ngân hàng không tồn tại và thực hiện các changeset một lần nữa, chỉ để kiểm tra xem changeset thực sự hoạt động. Kể từ khi Liquibase đã thay đổi của tôi trong nhật ký của nó, nó đã không được thực hiện một lần nữa. Vì vậy tôi không thể thấy sự thay đổi trong cơ sở dữ liệu. Tôi nhận thấy rằng khi tôi cuộn tất cả các thay đổi lại và cập nhật lại cơ sở dữ liệu.

Để thay đổi hoàn tất, tôi cũng phải xác định một lần khôi phục vì Liquibase không thể tự động cuộn lại các cập nhật hàng. Kể từ khi các ID của các tài khoản ngân hàng bị mất mãi mãi, tôi chỉ cần thêm một cuộn trống lệnh sau:

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
             http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> 
    <changeSet id="remove_fk_bankid" author="v7"> 
     <update tableName="DOCTOR"> 
      <column name="FK_BANKID" value="NULL" /> 
      <where>FK_BANKID NOT IN (SELECT ID FROM BANK)</where> 
     </update> 
     <rollback> 
     </rollback> 
    </changeSet> 
</databaseChangeLog> 
Các vấn đề liên quan