Używam OleDbDataAdapter i OleDbCommandBuilder do wypełniania obiektu DataSet zawartością bazy danych, a następnie aktualizowania bazy danych zgodnie ze zmianami wprowadzonymi w DataSet. Problem polega na tym, że otrzymuję wyjątek: "Naruszenie współbieżności: parametr UpdateCommand wpłynął na 0 oczekiwanych 1 rekordów". Znalazłem wyjaśnienie tego błędu:Uzyskiwanie wygenerowanych poleceń SQL przez OleDbCommandBuilder
Because a record could have been modified after it was returned from the SELECT statement, but before the UPDATE or DELETE statement is issued, the automatically generated UPDATE or DELETE statement contains a WHERE clause, specifying that a row is only updated if it contains all original values and has not been deleted from the data source. Where an automatically generated update attempts to update a row that has been deleted or that does not contain the original values found in the DataSet, the command does not affect any records, and a DBConcurrencyException is thrown.
To oznacza, że automatycznie wygenerowane polecenie UPDATE wpłynęło na 0 wierszy w bazie danych. Pracuję z bazą danych paradoks (db-file) i nikt jej nie zmienia oprócz mnie. Myślę, że mój program zmienia gdzieś ten sam wiersz dwa razy. Chciałem debugować mój program, wykonując ręcznie wszystkie wygenerowane zapytania i stwierdzając, który z nich nie ma wpływu na żaden wiersz (ponieważ właściwie jestem pewien, że wszystkie zmiany zostały wprowadzone tylko raz, a błąd jest gdzieś indziej))). Czy można uruchamiać automatycznie generowane polecenia ręcznie?
Mój kod jest zbyt duży i skomplikowany, aby opublikować go tutaj, ale ogólnie działa tak (Zrobiłem projekt roboczy i zabrał go stamtąd)
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OleDb;
namespace OleDBCommandBuilder
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string cs = @"Provider=Microsoft.Jet.OLEDB.4.0;";
cs += @"Data Source=C:\FOLDER\1\SPR_KMZ\;";
cs += @"Extended Properties=Paradox 5.x;";
OleDbConnection Connection = new OleDbConnection();
Connection.ConnectionString = cs;
try
{ Connection.Open(); }
catch (Exception ex)
{ MessageBox.Show("Error openning database! " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(0); }
string SQLQuery = "SELECT * FROM SPR_KMZ WHERE REZ<>0";
DataSet SPR_KMZ = new DataSet();
OleDbDataAdapter DataAdapter = new OleDbDataAdapter();
DataAdapter.SelectCommand = new OleDbCommand(SQLQuery, Connection);
OleDbCommandBuilder builder = new OleDbCommandBuilder(DataAdapter);
try
{
DataAdapter.Fill(SPR_KMZ);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(String.Format("Error \n{0}\n{1}", ex.Message, SQLQuery));
Environment.Exit(0);
}
DataRow[] SPR_KMZ_rows = SPR_KMZ.Tables[0].Select("Fkmz=10000912 AND REZ=1");
foreach (DataRow SPR_KMZ_row in SPR_KMZ_rows)
{
SPR_KMZ_row["DN"] = Convert.ToDateTime("30.12.1899");//26.12.2008
SPR_KMZ_row["Price"] = Convert.ToDouble(0);//168,92
}
DataAdapter.Update(SPR_KMZ);
System.Windows.Forms.MessageBox.Show("Success!");
Environment.Exit(0);
}
}
}
PS: Poprzednio aktualizował bazę danych bez wyjątku współbieżności, ale po wielu zmianach (przez długi czas komentowałem wiersz "DataAdapter.Update (SPR_KMZ) ;, więc nie wiem, kiedy dokładnie ten błąd zaczął się pojawiać rzut)
PSS nie istnieją żadne wstawia lub usuwa w moim kodu tylko aktualizacje ...
< <UPDATE> >
znalazłem w czym problem: jeśli „DN” pole ma wartość NULL następnie po zmianie go, automatycznie wygenerowana instrukcja UPDATE nie ma wpływu na nic, oczywiście dlatego, że "DN" jest zawarty w kluczu podstawowym, a program budujący polecenia nie oczekiwał, że pole klucza podstawowego będzie miało wartości NULL (kto kiedykolwiek by)), nie zdziwiłoby się tego silnika nazywa się "Paradox")))
dlatego w
CommandBuilder.GetUpdateCommand().CommandText
w którym klauzula dla "DN" pola nie było tego rodzaju wzoru:
... WHERE ((REZ = ?) AND (DN = ?) AND ...
podczas gdy pola dopuszczające wartość null są opisane tak:
... AND ((? = 1 AND Price IS NULL) OR (Price = ?)) AND ((? = 1 AND Nmed IS NULL) OR (Nmed = ?)) AND ...
P.S.S.S. Hej, mogę spróbować ustawić UpdateCommand ręcznie, aby to naprawić!)))
Czy istnieje możliwość dołączenia kodu, którego używasz? –
Wyszukaj brakującą instrukcję wstawiania lub instrukcję usuwania. Czy można zmniejszyć swój problem poprzez zmniejszenie liczby mutacji DataSet? –