sql >> データベース >  >> RDS >> Mysql

MySQLを更新すると、影響を受ける行が返されますが、実際にはデータベースは更新されません

    調べたい最も簡単な方法は、宛先テーブルを切り捨ててから、XMLインポートをそのテーブルに保存することです(AIをオフにして、必要に応じてインポートされたIDを使用します)。唯一の問題はそれを行う権利にあるかもしれません。それ以外の場合...

    あなたがやろうとしていることはほぼ Mergeを使用して処理します 方法。ただし、削除された行を認識できない/認識しません。 メソッドはDataTablesに作用しているため 、行がマスターデータベースで削除された場合、その行はXML抽出に存在しません(RowStateとは異なります)。 Deletedの )。これらはループで取り除くことができます。

    同様に、新しい行はAIintに対して異なるPKを取得する可能性があります。これを防ぐには、宛先データベースで単純な非AI PKを使用して、任意の数を受け入れることができるようにします。

    XMLの読み込み:

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

    マージコード:

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

    何らかの理由で、rowsChanged 常に合計行数と同じ数の変更を報告します。ただし、Master / XML DataTableからの変更は、other/destinationテーブルに流れます。

    削除コードは、既存のIDのリストを取得し、新しいXMLテーブルにそのIDの行があるかどうかによって、宛先DataTableから削除する必要のある行を決定します。欠落している行はすべて削除されてから、テーブルがマージされます。

    キーはdtSample.Merge(dtMaster,false, MissingSchemaAction.Add);です。 dtMasterからのデータをマージします dtSampleを使用 。 false paramは、着信XMLの変更が他のテーブルの値を上書きできるようにするものです(最終的にはデータベースに保存されます)。

    AI PKが一致しないなどの問題のいくつかが大きな問題であるかどうかはわかりませんが、これで私が見つけたすべての問題を処理できるようです。実際には、あなたがやろうとしているのはデータベースの同期 。テーブルが1つで、行が数行しかない場合でも、上記は機能するはずです。




    1. .frmおよび.optファイルをMySQLにインポートします

    2. データベースへの日付と時刻の挿入を防止する

    3. 更新時のリンクトデータエンティティの整合性

    4. 特定のクエリに対してPostgresでwork_memを設定する