Luiz Fernando Posted May 16, 2023 Report Share Posted May 16, 2023 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 Quote Link to comment Share on other sites More sharing options...
kapiaba Posted May 16, 2023 Report Share Posted May 16, 2023 https://pt.stackoverflow.com/questions/190690/como-comparar-a-estrutura-de-duas-tabelas-e-atualizar-a-outra https://pt.stackoverflow.com/questions/285909/comparar-registros-entre-duas-tabelas-no-mysql Aproveitando, o que é MONGODB? kkkkk https://revista.fatectq.edu.br/index.php/interfacetecnologica/article/download/664/411/ abs. Quote Link to comment Share on other sites More sharing options...
alex2002 Posted May 17, 2023 Report Share Posted May 17, 2023 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 Luiz Fernando 1 Quote Link to comment Share on other sites More sharing options...
Luiz Fernando Posted May 17, 2023 Author Report Share Posted May 17, 2023 Alex vlw por compartilhar sua rotina, era exatamente algo assim que eu queria, vou adaptar ele aqui, obg Kapiaba obg pelo retorno. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.