Clipper On Line • Ver Tópico - Coluna RowVersion em Tabela DBF

Coluna RowVersion em Tabela DBF

Discussão sobre Banco de Dados e RDDs para Clipper/[x]Harbour.

Moderador: Moderadores

 

Coluna RowVersion em Tabela DBF

Mensagempor alxsts » 20 Out 2018 05:47

Olá!

Ao ver a descrição desta característica...
^ RowVers 8 Row version number; modification count of this record
... 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.

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?
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Coluna RowVersion em Tabela DBF

Mensagempor Itamar M. Lins Jr. » 07 Jun 2021 20:10

Olá!
Tem um erro no seu fonte.
Screenshot_20210607_200838.png

   AAdd( aArray, { "cdRowVers", "^",  8, 0 } )   // ReadOnly 

Seu fonte está com 20 o tamanho.

Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6927
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 309 vezes
Mens.Curtidas: 503 vezes

Coluna RowVersion em Tabela DBF

Mensagempor alxsts » 07 Jun 2021 22:50

Olá!

Realmente está com valor errado. Executando o teste da forma como está, não houve mudança.
alxsts escreveu:Ao ver a descrição desta característica...
^ RowVers 8 Row version number; modification count of this record
... 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.

Realmente, é uma questão de entendimento do conceito aplicado. Funciona mas, de forma diferente do que eu imaginava. O número sequencial de atualizações é gerado com base no arquivo e não no registro. No exemplo, inseri de uma só vez 27 registros. Imaginei que cada registro iria receber Row version = 1. Ao ser alterado este Row version = 1, imaginei que seu Row version fosse alterado para 2. Mas não. Na inclusão, cada registro recebeu um Row version sequencial (igual ao autoincrement), variando de 1 até 27. Ao alterar o Row version número 1, este passou a ter o valor 28.

Conclusão: Row version é sempre atualizado com o último do arquivo + 1 e não (como eu pensava) com o último do registro + 1. Este fato não invalida a utilidade do recurso.

Valeu Itamar!
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Coluna RowVersion em Tabela DBF

Mensagempor Itamar M. Lins Jr. » 08 Jun 2021 07:56

Olá!
Também imaginei da mesma forma.
Mas podemos implementar MeuRowVer++ durante o replace.

Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6927
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 309 vezes
Mens.Curtidas: 503 vezes

Coluna RowVersion em Tabela DBF

Mensagempor alxsts » 08 Jun 2021 09:35

Olá!
Itamar M. Lins Jr. escreveu:Mas podemos implementar MeuRowVer++ durante o replace.

Não. Ele não deixa alterar. Não dá erro mas, ao final, a alteração não é feita.
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Coluna RowVersion em Tabela DBF

Mensagempor Itamar M. Lins Jr. » 08 Jun 2021 14:16

Olá!
Estava me referindo a um campo numérico comum.
O RowVers eu testei e vi que não deixa mexer.
No MSSQL é o mesmo comportamento, até pior pois não é decimal. 0X0888C...
Toda vez que altera ele muda pra alguma coisa que não era o original.

Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6927
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 309 vezes
Mens.Curtidas: 503 vezes




Retornar para Banco de Dados

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 10 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro