Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Cập nhật MySQL trả về các hàng bị ảnh hưởng, nhưng không thực sự cập nhật Cơ sở dữ liệu

Cách đơn giản nhất mà bạn có thể muốn xem xét có thể là TRUNCATE bảng đích, sau đó chỉ cần lưu nhập XML vào đó (tắt AI để nó sử dụng ID đã nhập nếu cần). Vấn đề duy nhất có thể là với quyền để làm điều đó. Nếu không ...

Những gì bạn đang cố gắng làm có thể hầu như được xử lý bằng cách sử dụng Merge phương pháp. Tuy nhiên, nó không thể / sẽ không biết về hàng đã xóa. Vì phương thức đang hoạt động trên DataTables , nếu một hàng đã bị xóa trong cơ sở dữ liệu chính, nó sẽ đơn giản không tồn tại trong phần trích xuất XML (so với một RowState trong tổng số Deleted ). Chúng có thể được loại bỏ bằng một vòng lặp.

Tương tự như vậy, bất kỳ hàng mới nào cũng có thể nhận được một PK khác cho một int AI. Để tránh điều đó, chỉ cần sử dụng PK đơn giản không phải AI trong db đích để nó có thể chấp nhận bất kỳ số nào.

Tải XML:

private DataTable LoadXMLToDT(string filename)
{
    DataTable dt = new DataTable();
    dt.ReadXml(filename);
    return dt;
}

Mã hợp nhất:

DataTable dtMaster = LoadXMLToDT(@"C:\Temp\dtsample.xml");
// just a debug monitor
var changes = dtMaster.GetChanges();

string SQL = "SELECT * FROM Destination";
using (MySqlConnection dbCon = new MySqlConnection(MySQLOtherDB))
{
    dtSample = new DataTable();
    daSample = new MySqlDataAdapter(SQL, dbCon);

    MySqlCommandBuilder cb = new MySqlCommandBuilder(daSample);
    daSample.UpdateCommand = cb.GetUpdateCommand();
    daSample.DeleteCommand = cb.GetDeleteCommand();
    daSample.InsertCommand = cb.GetInsertCommand();
    daSample.FillSchema(dtSample, SchemaType.Source);
    dbCon.Open();

    // the destination table
    daSample.Fill(dtSample);

    // handle deleted rows
    var drExisting = dtMaster.AsEnumerable()
                .Select(x => x.Field<int>("Id"));
    var drMasterDeleted = dtSample.AsEnumerable()
                .Where( q => !drExisting.Contains(q.Field<int>("Id")));

    // delete based on missing ID
    foreach (DataRow dr in drMasterDeleted)
        dr.Delete();

    // merge the XML into the tbl read
    dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);

    int rowsChanged = daSample.Update(dtSample);
}

Vì bất kỳ lý do gì, rowsChanged luôn báo cáo nhiều thay đổi vì có tổng số hàng. Nhưng những thay đổi từ Master / XML DataTable thực hiện luồng qua bảng kia / đích.

Mã xóa nhận danh sách các ID hiện có, sau đó xác định hàng nào cần được xóa khỏi DataTable đích bằng cách xem bảng XML mới có hàng có ID đó hay không. Tất cả các hàng bị thiếu sẽ bị xóa, sau đó các bảng được hợp nhất.

Khóa là dtSample.Merge(dtMaster,false, MissingSchemaAction.Add); hợp nhất dữ liệu từ dtMaster với dtSample . false param là thứ cho phép các thay đổi XML đến ghi đè các giá trị trong bảng khác (và cuối cùng được lưu vào db).

Tôi không biết liệu một số vấn đề như PK AI không khớp có phải là vấn đề lớn hay không, nhưng điều này dường như xử lý tất cả những gì tôi có thể tìm thấy. Trên thực tế, những gì bạn đang cố gắng làm là Đồng bộ hóa cơ sở dữ liệu . Mặc dù với một bảng và chỉ một vài hàng, những điều trên sẽ hoạt động.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. đặt lại mật khẩu gốc với cấu hình mysql sai

  2. Mối quan hệ truy vấn Mysql Bảng M-M

  3. Giữ lại các giá trị trường sau khi gửi

  4. MySQL lưu trữ các cạnh đồ thị vô hướng một cách hiệu quả

  5. Làm cách nào để tránh các kết nối DB bị đình trệ với nhóm kết nối JDBC của TomEE?