首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi RowVersion

Delphi RowVersion
EN

Stack Overflow用户
提问于 2017-07-21 04:32:40
回答 1查看 300关注 0票数 0

有没有人有使用SQL Server的RowVersion列和TClientDataset的经验?具体地说,我需要在insert时取回RowVersion值。它似乎在更新时取回了RowVersion值,但在新插入的行中却没有。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-21 17:10:58

这似乎涉及到一个类似的问题,当您需要使用带有标识字段的SqlServer表的CDS时,其中字段中的值是由服务器设置的,因此您在CDS端插入操作期间不知道它。在本文http://edn.embarcadero.com/article/20847中解释了一种方法。它涉及到在OnNewRecord事件中为CDS中的标识字段分配一个临时的负值,然后在通过调用ApplyUpdates将新记录发送到服务器后,使用CDS的Refresh方法检索服务器端标识字段值。

在D7中,我将这个答案作为一种最小公分母,这种技术似乎也适用于RowVersion字段。下面是一个示例项目的摘录。要使其正常工作,我必须将RowVersion字段定义为大小为8的ftBytes字段,并更改ProviderFlags,使其从AdoQuery的标识字段ID中排除pfInWherepfInUpdate

CDS中的RowVerStr字段只是为了在TDBGrid中清晰地显示值。

代码语言:javascript
复制
type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    DataSetProvider1: TDataSetProvider;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    ADOQuery1ID: TAutoIncField;  //  The ID field is an Identity field on the server
    ADOQuery1IntValue: TIntegerField;  //  a user field
    CDS1: TClientDataSet;
    CDS1ID: TAutoIncField;
    CDS1IntValue: TIntegerField;
    CDS1RowVersion: TBytesField;
    CDS1RowVerStr: TStringField;  //  just for display, fkInternalCalc, size = 20
    ADOQuery1RowVersion: TBytesField;
    procedure FormCreate(Sender: TObject);
    procedure CDS1AfterPost(DataSet: TDataSet);
    procedure CDS1AfterDelete(DataSet: TDataSet);
    procedure CDS1NewRecord(DataSet: TDataSet);
    procedure CDS1AfterInsert(DataSet: TDataSet);
    procedure CDS1CalcFields(DataSet: TDataSet);
  public
    FID : Integer;  //  To generate temporary value for CDS identity field
    function NextID : Integer;
  end;

[...]

function GetRowVerString(V : Variant) : String;
var
  i,
  Dim,
  Min,
  Max : Integer;
  i64 : Int64;
begin
  Result := '';
  if not VarIsArray(V) then Exit;
  Dim := VarArrayDimCount(V);
  Max := VarArrayHighBound(V, Dim);
  Min := VarArrayLowBound(V, Dim);

  for i := 0 to 7 do
    Int64Rec(i64).Bytes[i] := V[i];
  Result := IntToStr(i64);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //  CDS1ID is an ftAutoInc field, so we need to remove its read-only flag so
  //  that we can assign it a temporary negative value in the OnNewRecord event
  CDS1ID.ReadOnly := False;

  AdoQuery1RowVersion.ProviderFlags := AdoQuery1RowVersion.ProviderFlags - [pfInWhere, pfInUpdate];

  CDS1.Open;
  Caption := IntToStr(CDS1.RecordCount);
end;

procedure TForm1.CDS1AfterPost(DataSet: TDataSet);
begin
  if CDS1.ApplyUpdates(0) = 0 then
    CDS1.Refresh;
end;

procedure TForm1.CDS1AfterDelete(DataSet: TDataSet);
begin
  CDS1.ApplyUpdates(-1);
end;

function TForm1.NextID: Integer;
begin
  Dec(FID);
  Result := FID;
end;

procedure TForm1.CDS1NewRecord(DataSet: TDataSet);
begin
  CDS1.FieldByName('ID').AsInteger := NextID;
  CDS1.FieldByName('IntValue').AsInteger := Random(100);
end;

procedure TForm1.CDS1AfterInsert(DataSet: TDataSet);
begin
  CDS1.Post;
end;

procedure TForm1.CDS1CalcFields(DataSet: TDataSet);
begin
  CDS1RowVerStr.AsString := GetRowVerString(CDS1RowVersion.Value);
end;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45224668

复制
相关文章

相似问题

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