首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由SQL Server2008 R2中的不同客户端更新同一记录

由SQL Server2008 R2中的不同客户端更新同一记录
EN

Stack Overflow用户
提问于 2011-10-07 18:03:33
回答 2查看 1.7K关注 0票数 1

我正在用Delphi-2010在网络模式下使用SQL Server2008 R2开发一个应用程序。

我的问题是,在某些情况下,多个客户端打开相同的记录进行更新。

第一个客户端可以更新记录,但其他客户端不能,因为SQL SERVER找不到有问题的记录,因为它已被修改。应用程序应该在不通知客户端的情况下允许两次更新。

该表包含许多字段,客户端可以不使用SQL语句和UPDATEBATCH()更新其中的任何字段。

代码语言:javascript
复制
// 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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-07 19:21:40

我总是更喜欢使用纯SQL在数据库中实现,而不是依赖于数据集/表中的数据库抽象。

代码语言:javascript
复制
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的并发更新。

票数 2
EN

Stack Overflow用户

发布于 2011-10-07 20:13:03

既然您说您使用的是updatebatch,那么我假设您使用的是TADODataSet (或者TADOTable、TADOQuery)。

ADO如何生成update语句由记录集属性Update Criteria控制。默认值是adCriteriaUpdCols,这意味着update的where子句将所有修改过的字段与旧的/原始值进行比较。要使updatebatch只使用键列,您可以这样做。

代码语言:javascript
复制
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代码如下所示。

代码语言:javascript
复制
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中定义的

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7685737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档