
我正在用Delphi-2010在网络模式下使用SQL Server2008 R2开发一个应用程序。
我的问题是,在某些情况下,多个客户端打开相同的记录进行更新。
第一个客户端可以更新记录,但其他客户端不能,因为SQL SERVER找不到有问题的记录,因为它已被修改。应用程序应该在不通知客户端的情况下允许两次更新。
该表包含许多字段,客户端可以不使用SQL语句和UPDATEBATCH()更新其中的任何字段。
// Press UPDATE
procedure TarticleEditForm.saveButtonClick(Sender: TObject);
begin
if (articleCode.Text <> '') AND (counter.Text <> '') AND (articleLabel.Text <> '') AND (tbCombo.Text <> '') AND (griffeCombo.Text <> '') then begin
ADOArticleFind.SQL.Text := 'SELECT * FROM article WHERE ID<>''' + ADOArticle.FieldByName('ID').Value + ''' AND article=''' + articleCode.Text + ''' AND mode=''' + modeCombo.Text + ''' AND counter=''' + counter.Text + '''';
ADOArticleFind.Open;
// UPDATE
if ADOArticleFind.RecordCount = 0 then begin
// SET Date Modification
ADOArticle.FieldByName('dateModification').Value := Now;
ADOArticle.FieldByName('modifiePar').Value := mainForm.user;
ADOArticle.UpdateBatch();
// Update ArticleColor/ArticleTissu tables
ADOArticleColor.SQL.Text := 'UPDATE articleColor SET article=''' + articleCode.Text + ''', mode=''' + modeCombo.Text + ''', counter=''' + counter.Text + ''' WHERE article=''' + tmpArticleCode + ''' AND mode=''' + tmpMode + ''' AND counter=''' + tmpCounter + '''';
ADOArticleColor.ExecSQL;
ADOArticleTissu.SQL.Text := 'UPDATE articleTissu SET article=''' + articleCode.Text + ''', mode=''' + modeCombo.Text + ''', counter=''' + counter.Text + ''' WHERE article=''' + tmpArticleCode + ''' AND mode=''' + tmpMode + ''' AND counter=''' + tmpCounter + '''';
ADOArticleTissu.ExecSQL;
// create event log
mainForm.ADOUser.SQL.Text := 'SELECT * FROM users WHERE online=1 AND editArticleEvent=1 AND username<>''' + mainForm.user + '''';
mainForm.ADOUser.Open;
while not mainForm.ADOUser.Recordset.EOF do begin
mainForm.ADOMainEventLog.Insert;
mainForm.ADOMainEventLog.FieldByName('event').Value := 'Article modifié: ' + designationCombo.Text + ' ' + saisonCombo.Text + ' ' + articleCode.Text + '-' + modeCombo.Text + counter.Text + ' de ' + griffeCombo.Text;
mainForm.ADOMainEventLog.FieldByName('eventFrom').Value := mainForm.user;
mainForm.ADOMainEventLog.FieldByName('eventTo').Value := mainForm.ADOUser.FieldByName('username').Value;
mainForm.ADOMainEventLog.FieldByName('eventType').Value := 'editArticleEvent';
mainForm.ADOMainEventLog.UpdateBatch();
mainForm.ADOUser.Next;
end;
// Finish
Self.Close;
end
else begin
MessageBox(Application.Handle, 'Cet article existe déja.', 'GET© Driver', MB_ICONWARNING);
articleCode.SetFocus;
end;
end
else
MessageBox(Application.Handle, 'Champs obligatoire(s) manquant(s).', 'GET© Driver', MB_ICONWARNING);
end;发布于 2011-10-07 19:21:40
我总是更喜欢使用纯SQL在数据库中实现,而不是依赖于数据集/表中的数据库抽象。
Query1.SQL.Text:= 'UPDATE table1 SET a=:newvalue WHERE A=:oldvalue';
Query1.ParamByName('newvalue').AsString:= '1';
Query1.ParamByName('oldvalue').AsString:= '2';
Query1.Prepare;
Query1.ExecSQL;使用这样的代码,您可以设置任意多个SQL-server的并发更新。
发布于 2011-10-07 20:13:03
既然您说您使用的是updatebatch,那么我假设您使用的是TADODataSet (或者TADOTable、TADOQuery)。
ADO如何生成update语句由记录集属性Update Criteria控制。默认值是adCriteriaUpdCols,这意味着update的where子句将所有修改过的字段与旧的/原始值进行比较。要使updatebatch只使用键列,您可以这样做。
ADODataSet1.CommandText := 'select * from SomeTable';
ADODataSet1.Open;
ADODataSet1.Recordset.Properties['Update Criteria'].Value := adCriteriaKey;
ADODataSet1.Edit;
ADODataSet1.FieldByName('SomeColumn').AsString := 'New value';
ADODataSet1.Post;
ADODataSet1.UpdateBatch();上面的TADOQuery代码如下所示。
ADOQuery1.SQL.Text := 'select * from SomeTable';
ADOQuery1.Open;
ADOQuery1.Recordset.Properties['Update Criteria'].Value := adCriteriaKey;
ADOQuery1.Edit;
ADOQuery1.FieldByName('SomeTable').AsString := 'New value';
ADOQuery1.Post;
ADOQuery1.UpdateBatch();顺便说一下,adCriteriaKey是在ADOInt.pas中定义的
https://stackoverflow.com/questions/7685737
复制相似问题