sql >> Database >  >> RDS >> Mysql

Het bijwerken van MySQL retourneert de betreffende rijen, maar werkt de database niet echt bij

De eenvoudigste manier waarop u misschien wilt kijken, is door de bestemmingstabel AF te kappen en vervolgens de XML-import erop op te slaan (met AI uitgeschakeld, zodat indien nodig de geïmporteerde ID wordt gebruikt). Het enige probleem kan zijn met de rechten om dat te doen. Anders...

Wat u probeert te doen, kan bijna worden afgehandeld met behulp van de Merge methode. Het kan/wil echter niets weten over verwijderde rijen. Aangezien de methode werkt op DataTables , als een rij is verwijderd in de hoofddatabase, zal deze gewoon niet bestaan ​​​​in het XML-extract (versus een RowState van Deleted ). Deze kunnen worden verwijderd met een lus.

Evenzo kunnen nieuwe rijen een andere PK krijgen voor een AI int. Om dat te voorkomen, gebruikt u gewoon een eenvoudige niet-AI PK in de bestemmings-db, zodat het elk nummer kan accepteren.

Het laden van XML:

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

De samenvoegcode:

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

Om welke reden dan ook, rowsChanged rapporteert altijd zoveel wijzigingen als er totale rijen zijn. Maar wijzigingen van de Master/XML-gegevenstabel gaan wel door naar de andere/bestemmingstabel.

De verwijdercode krijgt een lijst met bestaande ID's en bepaalt vervolgens welke rijen moeten worden verwijderd uit de doelgegevenstabel door of de nieuwe XML-tabel een rij met die ID heeft of niet. Alle ontbrekende rijen worden verwijderd, waarna de tabellen worden samengevoegd.

De sleutel is dtSample.Merge(dtMaster,false, MissingSchemaAction.Add); die de gegevens van dtMaster . samenvoegt met dtSample . De false param zorgt ervoor dat de inkomende XML-wijzigingen waarden in de andere tabel kunnen overschrijven (en uiteindelijk worden opgeslagen in de db).

Ik heb geen idee of sommige van de problemen, zoals niet-overeenkomende AI PK's, een groot probleem zijn of niet, maar dit lijkt alles aan te pakken wat ik kon vinden. In werkelijkheid probeert u Databasesynchronisatie . Hoewel met één tabel en slechts een paar rijen, zou het bovenstaande moeten werken.




  1. CodeIgniter Database Query met behulp van query() met IN-clausule

  2. Waarom krijg ik Resource id #4 als ik print_r() toepas op een array in PHP?

  3. Hoe kan ik een waarde opvragen in de SQL Server XML-kolom?

  4. Kan mysql2 voor rails 3 niet installeren op Windows