2017-07-20 48 views

回答

3

这似乎涉及了类似的问题,当你需要使用CDS与 它有一个标识字段,其中在现场 值由服务器设置一个SQLServer表,所以你不知道在CDS侧插入操作期间。一种方法是在本文中解释 http://edn.embarcadero.com/article/20847。它涉及 在CDS 在OnNewRecord事件分配一个临时的,消极的,价值的标识字段,然后使用CDS的Refresh方法 检索服务器端的标识字段值,一旦新的纪录一直 发布致电ApplyUpdates致服务器。

在D7中,我正在将此答案用作最低公分母, 此技术似乎也适用于RowVersion字段。下面是一个示例项目的 摘录。得到它的工作,我必须定义 的RowVersion字段大小为8的ftBytes领域,改变 的ProviderFlags从 AdoQuery的身份字段,ID排除pfInWherepfInUpdate

CDS中的RowVerStr字段仅显示在TDBGrid中的值。

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; 
+0

'rowversion'是[用于'timestamp'同义词(实际上替换)](https://docs.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact -SQL)。 – Victoria

+0

@avidgolfer:这是否解决了您的问题? – MartynA

+0

@MartynA:您的解决方案确实有效。看起来过于健谈,但由于我无法控制的限制,我无法在自己的环境中实现它。 – avidgoffer