Ao ver a descrição desta caracterÃstica...
... imaginei que ao ser incluÃda uma linha na tabela, o valor da coluna seria inicializado com o valor zero (ou um) e a cada update seria incrementado em um.^ RowVers 8 Row version number; modification count of this record
Construà o programa abaixo para testar mas o resultado obtido não foi o esperado.
O contador é similar ao autoincrement, que também tenho na tabela destino. Como inclui uma massa de dados, ao final os dois contadores ficaram com o mesmo valor. Quando se altera algum registro, a coluna do tipo rowversion recebe o valor da ultima alteração global na tabela acrescido de um e não o valor atual da coluna rowversion daquela linha acrescido de um, como imaginei.
Alguém sabe se isto é um bug ou se fui eu quem imaginou errado?
#include "set.ch"
#define lKeepOpen .T.
Function Main()
LOCAL aArray, e, cScreen := SaveScreen()
REQUEST DBFCDX
REQUEST HB_LANG_PT
REQUEST HB_CODEPAGE_UTF8
hb_CdpSelect( "UTF8" )
RDDSetDefault( "DBFCDX" )
Set( _SET_AUTOPEN, .T. )
Set( _SET_DATEFORMAT, "dd-mm-yyyy" )
/* Novos Tipos de Coluna
D Date 3, 4 or 8 Date
M Memo 4 or 8 Memo
+ AutoInc 4 Auto increment
= ModTime 8 Last modified date & time of this record
**************************************************************************************
^ RowVers 8 Row version number; modification count of this record *
**************************************************************************************
@ DateTime 8 Date & Time
I Integer 1, 2, 3, 4 or 8 Signed Integer ( Width : )" },;
T Time 4 or 8 Only time (if width is 4 ) or Date & Time (if width is 8 ) (?)
V Variant 3, 4, 6 or more Variable type Field
Y Currency 8 64 bit integer with implied 4 decimal
B Double 8 Floating point / 64 bit binary
*/
aArray := {}
AAdd( aArray, { "idUF", "+", 4, 0 } ) // ReadOnly
AAdd( aArray, { "idCountry", "N", 4, 0 } )
AAdd( aArray, { "sgSigla", "C", 2, 0 } )
AAdd( aArray, { "nmEstado", "C", 50, 0 } )
AAdd( aArray, { "dtDateIns", "@", 8, 0 } )
AAdd( aArray, { "nmUserIns", "C", 20, 0 } )
AAdd( aArray, { "dtDateUpd", "=", 8, 0 } )
AAdd( aArray, { "nmUserUpd", "C", 20, 0 } )
AAdd( aArray, { "cdRowVers", "^", 20, 0 } ) // ReadOnly
/*********************************************************
Segundo Harbour Reference Guide
dbCreate()
Creates an empty database from a array.
Syntax
dbCreate( <cFile>, <aStruct>, [<cRDD>], [<lKeepOpen>], [<cAlias>],
[<cDelimArg>], [<cCodePage>], [<nConnection>] )
Arguments
cFile Name of database file to be create
aStruct Name of a multidimensional array that contains the
database structure
cRDD Name of the RDD
lKeepOpen 3-way toggle to Open the file in New or Current work area:
NIL The file is not opened.
True It is opened in a New area.
False It is opened in the current area.
cAlias Name of database Alias
DBCREATE("tbState", aArray, "DBFCDX", lKeepOpen ) ==> RT Error BASE/1002 Alias does not exist: TBSTATE
em ORDCREATE( , "idUF", "tbState->idUF", { || tbState->idUF } )
*********************************************************/
DBCREATE("tbState", aArray, "DBFCDX", )
DBUSEAREA( .T.,"DBFCDX", "tbState", "tbState", .F., .F. )
ORDCREATE( , "idUF", "tbState->idUF", { || tbState->idUF } )
ORDCREATE( , "sgSigla", "tbState->sgSigla", { || tbState->sgSigla } )
aArray := {}
Aadd( aArray, { 'AC', 'Acre' } )
Aadd( aArray, { 'AL', 'Alagoas' } )
Aadd( aArray, { 'AP', 'Amapá' } )
Aadd( aArray, { 'AM', 'Amazonas' } )
Aadd( aArray, { 'BA', 'Bahia' } )
Aadd( aArray, { 'CE', 'Ceará' } )
Aadd( aArray, { 'DF', 'Distrito Federal' } )
Aadd( aArray, { 'ES', 'EspÃrito Santo' } )
Aadd( aArray, { 'GO', 'Goiás' } )
Aadd( aArray, { 'MA', 'Maranhão' } )
Aadd( aArray, { 'MT', 'Mato Grosso' } )
Aadd( aArray, { 'MS', 'Mato Grosso do Sul' } )
Aadd( aArray, { 'MG', 'Minas Gerais' } )
Aadd( aArray, { 'PA', 'Pará' } )
Aadd( aArray, { 'PB', 'ParaÃba' } )
Aadd( aArray, { 'PR', 'Paraná' } )
Aadd( aArray, { 'PE', 'Pernambuco' } )
Aadd( aArray, { 'PI', 'PiauÃ' } )
Aadd( aArray, { 'RJ', 'Rio de Janeiro' } )
Aadd( aArray, { 'RN', 'Rio Grande do Norte' } )
Aadd( aArray, { 'RS', 'Rio Grande do Sul' } )
Aadd( aArray, { 'RO', 'Rondônia' } )
Aadd( aArray, { 'RR', 'Roraima' } )
Aadd( aArray, { 'SC', 'Santa Catarina' } )
Aadd( aArray, { 'SP', 'São Paulo' } )
Aadd( aArray, { 'SE', 'Sergipe' } )
Aadd( aArray, { 'TO', 'Tocantins'} )
For Each e in aArray
tbState->( DbAppend() )
If ! NetErr()
//tbState->idUF Autoincrement ReadOnly
tbState->idCountry := 1
tbState->sgSigla := e[ 1 ]
tbState->nmEstado := e[ 2 ]
tbState->dtDateIns := hb_DateTime()
tbState->nmUserIns := "Sistema"
//tbState->dtDateUpd // ReadOnly
tbState->nmUserUpd := ""
//tbState->cdRowVers // ReadOnly
Else
Alert( "Erro ao inserir registro " + Str( e:__enumIndex() ) )
Endif
Next
tbState->( DbGoTop(), ;
Browse(), ;
DbEval( { || tbState->nmEstado := Upper( tbState->nmEstado ) } ), ;
DbGoTop(), ;
Browse(), ;
DbCloseArea() ;
)
RestScreen( ,,,,cScreen )
RETURN NIL
//------------------------------------------------------------------------------
De qualquer forma, é um tipo de campo importante para controlar alterações concorrentes na mesma linha de uma tabela.
- Lê o registro e exibe (em um tbrowse, por exemplo)
- Se usuário seleciona alteração, guarda este campo e permite que o usuário altere
- Se confirmar a alteração, relê o registro e compara os campos de versão
- Se iguais, executa alteração. Caso contrário, erro - alguém alterou o registro antes
De quebra, ainda peguei um bug ou divergência entre a prática e a documentação (Harbour Reference Guide)
/*********************************************************
Segundo Harbour Reference Guide
dbCreate()
Creates an empty database from a array.
Syntax
dbCreate( <cFile>, <aStruct>, [<cRDD>], [<lKeepOpen>], [<cAlias>],
[<cDelimArg>], [<cCodePage>], [<nConnection>] )
Arguments
cFile Name of database file to be create
aStruct Name of a multidimensional array that contains the
database structure
cRDD Name of the RDD
lKeepOpen 3-way toggle to Open the file in New or Current work area:
NIL The file is not opened.
True It is opened in a New area.
False It is opened in the current area.
cAlias Name of database Alias
DBCREATE("tbState", aArray, "DBFCDX", lKeepOpen ) ==> RT Error BASE/1002 Alias does not exist: TBSTATE
em ORDCREATE( , "idUF", "tbState->idUF", { || tbState->idUF } )
*********************************************************/
Alguém poderia, por favor, reportar isso aos desenvolvedores?