Jump to content
Fivewin Brasil

Comparar Estrutura tabela MYSQL


Luiz Fernando

Recommended Posts

Pessoal não custa perguntar, as vezes alguém tem algo e possa compartilhar, eu tenho uma rotina para criar uma tabela, o sistema verifica se ela existe, caso contrario cria, até ai tudo bem.

queria montar algo do tipo, aonde se existir, verifica os campos, imagina que o no exemplo abaixo o campo geral campo geral varchar(01) foi criada numa nova versão, e do cliente não tenha esse campo

 

  IF (! TABLE("ccusto"))
     MsgRun("Cadastro de centro de custo",revenda)
     ::cSql:="CREATE TABLE ccusto"
     ::cSql+="("
     ::csql+="codigo varchar(02) unique "  	   
     ::csql+=",nome varchar(30) unique "   
     ::csql+=",tipo varchar(01) "  
     ::csql+=",geral varchar(01) "  
 	  ::cSql+=",sql_rowid bigint(10) unsigned NOT NULL AUTO_INCREMENT"  
	  ::cSql+=",deletado enum('F','T') DEFAULT 'F'"    
	  ::cSql+=",PRIMARY KEY (sql_rowid)"
  	  ::cSql+=")engine=InnoDB"
     TExecute():New(::cSql)
  ENDIF

hj trabalho da seguinte forma, tenho um controle de versão, aonde vou atualizando versão a versão, isso até que funciona no meu sistema principal, mais num novo projeto queria ver se tem como fazer isso de outra forma

function atualiza_versao_0276()
  private oDlgg
  SQLBeginTrans()
  cSql:="alter table tarefas add projeto VARCHAR(03) "
  SqlExecute(cSql)
  if SQLErrorNO() > 0
     fMensagem()
  endif
  SqlExecute("commit")
  SQLRollBack()
  SQLEndTrans()
  SQLRefresh()

  SQLBeginTrans()
  cSql:="alter table oscrm_a add projeto VARCHAR(3) "
  SqlExecute(cSql)
  if SQLErrorNO() > 0
     fMensagem()
  endif
  SqlExecute("commit")
  SQLRollBack()
  SQLEndTrans()
  SQLRefresh()
return

 

Link to comment
Share on other sites

Bom dia Luiz.

Este código meu faz exatamente o que vc precisa. Eu rodo a verificação de tabelas todas as vezes que muda uma versão. Sendo assim, nunca mais precisei me preocupar com estrutura de banco de clientes. E quando mudo alguma coisa, basta eu colocar no array que define a estrutura da tabela. Só isso.

 

cTabela := cBanco+'.ase_log'  // Tabela de logs de documentos assinados eletrônicamente
aCampos := {}

//                Campo             Tipo            NULL?  Default  Comentário (isso vira um dicionário de dados depois)
aadd( aCampos, { 'CCO_CONTA',       'CHAR(9)',      '',    '',      'Código da Conta Corrente' } )
aadd( aCampos, { 'ASE_NDOC',        'CHAR(10)',     '',    '',      'Número do Contrato' } )
aadd( aCampos, { 'ASE_PARCEIRO',    'INT(1)',       '',    '0',     'Código do parceiro: 1-ClickSign' } )
aadd( aCampos, { 'ASE_ARQUIVO',     'VARCHAR(50)',  '',    '',      'Nome do arquivo' } )
aadd( aCampos, { 'ASE_TOKEN',       'MEDIUMBLOB',   '',    '',      'Token do arquivo devolvido pelo parceiro de assinatura eletrônica' } )
VerificaTabela( cTabela, aCampos )

////////////////////////////DADOS DA FUNCAO////////////////////////////////////////////
// NOME       : VerificaTabela                                                       //
// SINTESE    : Verificar a estrutura da tabela e atualiza                           //
// PARAMETROS : <1> cTabela   = Nome da Tabela                                       //
//              <2> aCampos   = Estrutura dos campos                                 //
//              [3] cChave Primária  (Default SQL_ROWID)                             //
//              [4] lAutoIncrement  (Default .t. )                                   //
// RETORNO    : lExecutou                                                            //
///////////////////////////////////////////////////////////////////////////////////////
function VerificaTabela( cTabela, aCampos, cChavePrimaria, lAutoIncrement )
local aSql
local cCmdSql
local cNomeA, cTipoA, cDefaultA, cComentA, cNullA
local cNomeB, cTipoB, cDefaultB, cComentB, cNullB
local nEncontrado
local i
local lRetorno := .t.
local lSetExact := set(_SET_EXACT, .t.)

default cChavePrimaria := 'SQL_ROWID'
defaulT lAutoIncrement := .t.

if !Table( cTabela )
    CriaTabela( aCampos, cTabela, cChavePrimaria, lAutoIncrement )
    
    // Verificando se criou
    if !Table( cTabela )
       lRetorno := .f.
    endif
    set(_SET_EXACT, lSetExact )
    return lRetorno
endif

aEstrutura := SqlArray('show full columns from '+cTabela )

for i = 1 to len( aCampos )
   cCampoA   := rtrim( aCampos[i,1] ) 
   cTIpoA    := strtran( aCampos[i,2], ' ', '') 
   cNullA    := aCampos[i,3]
   cDefaultA := aCampos[i,4]
   cCommentA := aCampos[i,5]
   
   if len( aCampos ) >= 6 .and. aCampos[i,6] 
      cDefaultX := aCampos[i,4]
   else
      cDefaultX := '"'+aCampos[i,4]+'"'
   endif
      


   nEncontrado := ascan( aEstrutura, {| x | lower( cCampoA ) == lower( x[1] ) } )
   if nEncontrado <> 0
      cCampoB    := rtrim( alltrim(aEstrutura[nEncontrado,1]) )
      cTipoB     := strtran( alltrim(aEstrutura[nEncontrado,2]), "'", '"' )
      cNullB     := alltrim(aEstrutura[nEncontrado,4])
      if lower(cNullB)  = 'yes'
          cNullB  := ''
      endif
      cDefaultB  := alltrim(aEstrutura[nEncontrado,6])
      cCommentB  := alltrim(aEstrutura[nEncontrado,9])
      
      // Verificando se houve mudança na estrutura
      if lower(cCampoA) <> lower(cCampoB) .or. lower(cTipoA) <> lower(cTipoB) .or. lower(cNullA) <> lower(cNullB) .or. lower(cDefaultA) <> lower(cDefaultB) .or. lower(cCommentA) <> lower(cCommentB)
         // Verificando se o campo é númerico e se realmente mudou
         
         if lower(cCampoA) = lower(cCampoB) .and. lower(cTipoA) = lower(cTipoB) .and. lower(cNullA) = lower(cNullB) .and. lower(cCommentA) = lower(cCommentB) .and. ( len( sonumeros( cDefaultA ) ) <> 0 .or. len( sonumeros( cDefaultB ) ) <> 0 )

            // Verificando o valor default
                if strzero( val( cDefaultA ), 30, 10 ) = strzero( val( cDefaultB ), 30, 10 ) 
               loop
            endif

            endif
            
         if lower(cCampoA) = lower(cCampoB) .and. lower(cTipoA) = lower(cTipoB) .and. lower(cCommentA) = lower(cCommentB) .and. lower(cNullA) <> lower(cNullB)
            // Verificando condição do NULL
            if empty(cNullA) .and. lower(cNullB) = 'no'
               loop
            endif

         endif
         // Fim
             
    //         ? cTabela, 'campo', lower(cCampoA), lower(cCampoB), 'tipo', lower(cTipoA), lower(cTipoB), 'null', lower(cNullA), lower(cNullB), 'default', lower(cDefaultA) , lower(cDefaultB), 'comment', lower(cCommentA), lower(cCommentB)

         if upper(cCampoA) = cChavePrimaria .and. lAutoIncrement
            cCmdSql := 'ALTER TABLE '+cTabela+' DROP '+cCampoA
            if !SqlExecute( cCmdSql )
               lRetorno := .f.
            endif
      
              cCmdSql := 'ALTER TABLE '+cTabela+' '
                cCmdSql += 'ADD '+cCampoA+' '+cTipoA+' '
                cCmdSql += if(cNullA = 'NO','NOT NULL','')+' '
                cCmdSql += if(!empty(cDefaultX) .and. cDefaultX <> '""','DEFAULT '+cDefaultX,'')+' '
                cCmdSql += if(!empty(cCommentA),'COMMENT "'+cCommentA+'"','')+' '
                if upper(cCampoA) = cChavePrimaria            
                   cCmdSql += 'PRIMARY KEY '+if( lAutoIncrement, 'AUTO_INCREMENT','')+' '
              endif
               cCmdSql += if( i > 1, 'AFTER '+aCampos[i-1,1],'FIRST') 
         else
             cCmdSql := 'ALTER TABLE '+cTabela+' '
                cCmdSql += 'MODIFY COLUMN '+cCampoA+' '+cTipoA+' '
                cCmdSql += if(cNullA = 'NO','NOT NULL','')+' '
                cCmdSql += if(!empty(cDefaultX) .and. cDefaultX <> '""' ,'DEFAULT '+cDefaultX,'')+' '
                cCmdSql += if(!empty(cCommentA),'COMMENT "'+cCommentA+'"','')+' '
                if upper(cCampoA) = cChavePrimaria            
                   cCmdSql += 'PRIMARY KEY '+if( lAutoIncrement, 'AUTO_INCREMENT','') 
             endif
            endif
 
          if !SqlExecute( cCmdSql )
             lRetorno := .f.
          endif
        endif
   else   
      cCmdSql := 'ALTER TABLE '+cTabela+' '
        cCmdSql += 'ADD '+cCampoA+' '+cTipoA+' '
        cCmdSql += if(cNullA = 'NO','NOT NULL','')+' '
        cCmdSql += if(!empty(cDefaultX) .and. cDefaultX <> '""','DEFAULT '+cDefaultX,'')+' '
        cCmdSql += if(!empty(cCommentA),'COMMENT "'+cCommentA+'"','')+' '
        if upper(cCampoA) = cChavePrimaria            
           cCmdSql += 'PRIMARY KEY '+if( lAutoIncrement, 'AUTO_INCREMENT','')+' '
      endif
       cCmdSql += if( i > 1, 'AFTER '+aCampos[i-1,1],'FIRST') 
      if !SqlExecute( cCmdSql )
         lRetorno := .f.
      endif
   endif
next

// Limpando campos que não existem na estrutura e que estão na tabela
for i = 1 to len( aEstrutura )
   cCampoA   := aEstrutura[i,1]  
   if upper(cCampoA) = 'SQL_ROWID' .or. upper(cCampoA) = 'SQL_DELETED'
      loop
   endif

    nEncontrado := ascan( aCampos, {| x | lower( cCampoA ) == lower( x[1] ) } )
   if nEncontrado = 0
      cCmdSql := 'ALTER TABLE '+cTabela+' DROP '+cCampoA
      if !SqlExecute( cCmdSql )
         lRetorno := .f.
      endif
   endif
next
//    
SysRefresh()
set(_SET_EXACT, lSetExact )
                 
return lRetorno
 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...