Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Memperbarui MySQL mengembalikan baris yang terpengaruh, tetapi tidak benar-benar memperbarui Database

Cara paling sederhana yang mungkin ingin Anda lihat adalah dengan MEMOTONG tabel tujuan, lalu cukup simpan impor XML ke dalamnya (dengan AI mati sehingga menggunakan ID yang diimpor jika perlu). Satu-satunya masalah mungkin dengan hak untuk melakukan itu. Jika tidak...

Apa yang Anda coba lakukan dapat hampir ditangani menggunakan Merge metode. Namun, itu tidak dapat/tidak akan mengetahui tentang baris yang dihapus. Karena metode ini bekerja pada DataTables , jika sebuah baris dihapus dalam database master, baris tersebut tidak akan ada dalam ekstrak XML (dibandingkan dengan RowState dari Deleted ). Ini dapat disingkirkan dengan satu putaran.

Demikian juga, setiap baris baru mungkin mendapatkan PK yang berbeda untuk int AI. Untuk mencegahnya, cukup gunakan PK non-AI sederhana di db tujuan sehingga dapat menerima nomor apa pun.

Pemuatan XML:

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

Kode gabungan:

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);
}

Untuk alasan apa pun, rowsChanged selalu melaporkan perubahan sebanyak jumlah baris. Namun perubahan dari Master/XML DataTable mengalir ke tabel lain/tujuan.

Kode hapus mendapatkan daftar ID yang ada, lalu menentukan baris mana yang perlu dihapus dari DataTable tujuan dengan apakah tabel XML baru memiliki baris dengan ID tersebut atau tidak. Semua baris yang hilang dihapus, lalu tabel digabungkan.

Kuncinya adalah dtSample.Merge(dtMaster,false, MissingSchemaAction.Add); yang menggabungkan data dari dtMaster dengan dtSample . false param adalah apa yang memungkinkan perubahan XML yang masuk untuk menimpa nilai di tabel lain (dan akhirnya disimpan ke db).

Saya tidak tahu apakah beberapa masalah seperti AI PK yang tidak cocok adalah masalah besar atau tidak, tetapi ini tampaknya menangani semua yang dapat saya temukan. Pada kenyataannya, apa yang Anda coba lakukan adalah Sinkronisasi Basis Data . Meskipun dengan satu tabel, dan hanya beberapa baris, hal di atas akan berfungsi.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bisakah injeksi SQL dicegah hanya dengan menambahkan bulu mata (string)?

  2. OSX ld:perpustakaan tidak ditemukan untuk -lssl

  3. Bagaimana cara membuat database dengan doktrin2?

  4. Pengoptimalan dan pengindeksan kinerja Mysql InnoDB

  5. Bagaimana tepatnya menggunakan OR dalam pernyataan MySQL berbeda dengan/tanpa tanda kurung?