Edu Posted May 22, 2015 Report Share Posted May 22, 2015 Prezados, Boa tarde! Estou usando SqlRdd com banco de dados MYSQL e estou implementando uma rotina de alteração de estrutura das tabelas. Eu vi que o SQLRDD tem a função ChangeStruct(), porém não consegui fazer funcionar. Alguém tem uma rotina semelhante que possa me ajudar? Grato. Ronaldbuch 1 Quote Link to comment Share on other sites More sharing options...
Eroni Posted May 22, 2015 Report Share Posted May 22, 2015 Boa tarde, ai está o que eu uso, resumidamente: AAdd( aCampos, { "c001fili_", "c", 04, 00, " " } ) // codigo da empresa AAdd( aCampos, { "c001codi_", "c", 06, 00, " " } ) // codigo AAdd( aCampos, { "c001aliq_", "n", 18, 03, 0 } ) // % aliquota AAdd( aCampos, { "c001redu_", "n", 18, 03, 0 } ) // % de reducao AAdd( aCampos, { "c001obse_", "c", 80, 00, " " } ) // observacoes SW_ChangeStruct( "arq001", aCampos ) ******************************************************************************************* ******************************************************************************************* /* * Altera a estrutura de uma tabela */ ******************************************************************************************* ******************************************************************************************* FUNCTION SW_ChangeStruct( cTable, aNew ) LOCAL lRet := .T. LOCAL aOld LOCAL cName, cType, nDec, nCols, cNull, nLen, cStr, cAfter, cDef LOCAL nLenOld, nDecOld, a LOCAL oSql := SR_GetConnection() LOCAL cSql := "" LOCAL cStrDef,nAt,aArray cTable := Upper( cTable ) IF cTable <> NIL .AND. ValType( aNew ) == "A" .AND. Len( aNew ) > 0 DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cSql := "Select * from " + cTable + " LIMIT 1 " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cSql := "Select TOP 1 * from " + cTable CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cSql := "Select * from " + cTable + " WHERE ROWNUM < 2 " OTHERWISE ; cSql := "Select * from " + cTable ENDCASE oSql:Execute( cSql ) oSql:IniFields( .F. ) aOld := oSql:AFields cStr := "" nCols := Len( aNew ) FOR a := 1 TO nCols SysRefresh() // reapresentar os controles cName := Upper( aNew[ a, 1 ] ) cType := aNew[ a, 2 ] nLen := aNew[ a, 3 ] nDec := aNew[ a, 4 ] cStrDef := aNew[ a, 5 ] cAfter := "" cDef := "" cNull := "NOT NULL " IF Upper( cType ) <> "D" // descobrir qual a coluna a ser alterada nAt := AScan( aOld, { | x | AllTrim( Upper( x[ 1 ] ) ) == AllTrim( Upper( cName ) ) } ) IF nAt > 0 // Verificar se o tamanho e decimal dos campos foram alterados nLenOld := aOld[ nAt, 3 ] nDecOld := aOld[ nAt, 4 ] IF nLen <> nLenOld // tamanho diferente cStr += "ALTER TABLE " + cTable + " " DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " MODIFY COLUMN " + cName + " " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " ALTER COLUMN " + cName + " " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " MODIFY " + cName + " " ENDCASE DO CASE CASE Upper( cType ) == "D" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " date " ; cDef := "DEFAULT '00000000' " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " smalldatetime " ; cDef := "DEFAULT (GetDate()) " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " date " ; cDef := "DEFAULT SYSDATE " ENDCASE CASE Upper( cType ) == "N" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " double(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := IF( cStrDef <> 0, "DEFAULT "+AllTrim(Str(cStrDef)),"DEFAULT 0 " ) CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " decimal(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := "DEFAULT 0 " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " number(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := "DEFAULT 0 " ENDCASE CASE Lower( cType ) == "c" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " char(" + AllTrim( Str( nLen, 3 ) ) + ") " ; cDef := IF( Len(cStrDef) > 0, "DEFAULT '"+AllTrim(cStrDef)+"'","DEFAULT ' ' " ) CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " char(" + AllTrim( Str( nLen, 3 ) ) + ") " ; cDef := " " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " char(" + AllTrim( Str( nLen, 3 ) ) + ") " ; cDef := "DEFAULT ' ' " ENDCASE CASE Lower( cType ) == "m" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " MEDIUMBLOB " ; cDef := "" //IF( Len(cStrDef) > 0, "DEFAULT '"+AllTrim(Str(cStrDef))+"'","DEFAULT ' ' " ) CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " TEXT " ; cDef := "" CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " LONG " ; cDef := "DEFAULT ' ' " ENDCASE ENDCASE IF Upper( oSistema:cDbDriver_ ) == "ORACLE" cStr += cAfter cStr += cDef cStr += cNull cStr := Lower( cStr ) + ";" ELSE cStr += cNull cStr += cDef cStr += cAfter cStr := Lower( cStr ) + ";" ENDIF ELSE // somente verificar se o decimal é diferente IF Upper( cType ) <> "C" .AND. Upper( cType ) <> "D" // tipo char e data nao temn decimal IF nDec <> nDecOld cStr += "ALTER TABLE " + cTable + " " DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " MODIFY COLUMN " + cName + " " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " ALTER COLUMN " + cName + " " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " MODIFY " + cName + " " ENDCASE DO CASE CASE Lower( cType ) == "d" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " date " ; cDef := "DEFAULT '00000000' " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " smalldatetime " ; cDef := "DEFAULT (GetDate()) " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " date " ; cDef := "DEFAULT sysdate " ENDCASE CASE Lower( cType ) == "n" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " double(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := IF( cStrDef <> 0, "DEFAULT "+AllTrim(Str(cStrDef)),"DEFAULT 0 " ) CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " decimal(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := "DEFAULT 0 " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " NUMBER(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := "DEFAULT 0 " ENDCASE CASE Lower( cType ) == "c" cStr += " char(" + AllTrim( Str( nLen, 3 ) ) + ") " ; cDef := IF( Len(cStrDef) > 0, "DEFAULT '"+AllTrim(Str(cStrDef))+"'","DEFAULT ' ' " ) CASE Lower( cType ) == "m" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " MEDIUMBLOB " ; cDef := "" //IF( Len(cStrDef) > 0, "DEFAULT '"+AllTrim(Str(cStrDef))+"'","DEFAULT ' ' " ) CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " TEXT " ; cDef := "" CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " LONG " ; cDef := "DEFAULT ' ' " ENDCASE ENDCASE IF Upper( oSistema:cDbDriver_ ) == "ORACLE" cStr += cAfter cStr += cDef cStr += cNull cStr := Lower( cStr ) + ";" ELSE cStr += cNull cStr += cDef cStr += cAfter cStr := Lower( cStr ) + ";" ENDIF ENDIF ENDIF ENDIF ELSE // else do at > 0 //nao achou o campo, criar o campo nao encontrado cStr += "ALTER TABLE " + cTable + " " cStr += " ADD " + cName + " " IF a > 1 IF Upper( oSistema:cDbDriver_ ) == "MYSQL" cAfter := " AFTER " + aNew[ a - 1, 1 ] + " " ENDIF ENDIF DO CASE CASE Lower( cType ) == "d" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " date " ; cDef := "DEFAULT '00000000' " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " smalldatetime " ; cDef := "DEFAULT (GetDate()) " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " DATE " ; cDef := "DEFAULT SYSDATE " ENDCASE CASE Lower( cType ) == "n" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " double(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := IF( cStrDef <> 0, "DEFAULT "+AllTrim(Str(cStrDef)),"DEFAULT 0 " ) CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " decimal(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := "DEFAULT 0 " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " NUMBER(" + AllTrim( Str( nLen, 3 ) ) + "," + AllTrim( Str( nDec ) ) + ") " ; cDef := "DEFAULT 0 " ENDCASE CASE Lower( cType ) == "c" ; cStr += " char(" + AllTrim( Str( nLen ) ) + ") " ; cDef := IF( Len(cStrDef) > 0 , "DEFAULT '"+AllTrim(cStrDef)+"'","DEFAULT ' ' " ) CASE Lower( cType ) == "m" DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " MEDIUMBLOB " ; cDef := "" /* IF( Len(cStrDef) > 0, "DEFAULT '"+AllTrim(Str(cStrDef))+"'","DEFAULT ' ' " )*/ ; cNull := "" CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " TEXT " ; cDef := "" CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " LONG " ; cDef := "DEFAULT ' ' " ENDCASE ENDCASE IF Upper( oSistema:cDbDriver_ ) == "ORACLE" cStr += cAfter cStr += cDef cStr += cNull cStr := Lower( cStr ) + ";" ELSE cStr += cNull cStr += cDef cStr += cAfter cStr := Lower( cStr ) + ";" ENDIF ENDIF ELSE // se for tipo DATA // descobrir qual a coluna a ser inserida nAt := AScan( aOld, { | x | AllTrim( Upper( x[ 1 ] ) ) == AllTrim( Upper( cName ) ) } ) IF nAt = 0 //nao achou o campo, criar o campo nao encontrado cStr += "ALTER TABLE " + cTable + " " cStr += " ADD " + cName + " " IF a > 1 IF Upper( oSistema:cDbDriver_ ) == "MYSQL" cAfter := " AFTER " + aNew[ a - 1, 1 ] + " " ENDIF ENDIF DO CASE CASE Upper( oSistema:cDbDriver_ ) == "MYSQL" ; cStr += " date " ; cDef := "DEFAULT '00000000' " CASE Upper( oSistema:cDbDriver_ ) == "MSSQLSERVER" ; cStr += " smalldatetime " ; cDef := "DEFAULT (GetDate()) " CASE Upper( oSistema:cDbDriver_ ) == "ORACLE" ; cStr += " DATE " ; cDef := "DEFAULT SYSDATE " ENDCASE IF Upper( oSistema:cDbDriver_ ) == "ORACLE" cStr += cAfter cStr += cDef cStr += cNull cStr := Lower( cStr ) + ";" ELSE cStr += cNull cStr += cDef cStr += cAfter cStr := Lower( cStr ) + ";" ENDIF ENDIF ENDIF NEXT a cStr := AllTrim( cStr ) IF Len( cStr ) > 0 aArray := ListAsArray( cStr , ";" ) IF Len( aArray ) > 0 FOR a := 1 TO Len( aArray ) IF Len( aArray[ a ] ) > 0 IF ! SWExecSql( Upper(aArray[ a ]),.F. ) lRet := .F. EXIT ENDIF ENDIF NEXT a ENDIF ENDIF ENDIF RETURN( lRet ) Quote Link to comment Share on other sites More sharing options...
Edu Posted May 23, 2015 Author Report Share Posted May 23, 2015 Obrigado Eroni! Vou testar aqui. Quote Link to comment Share on other sites More sharing options...
Edu Posted May 23, 2015 Author Report Share Posted May 23, 2015 Eroni, Preciso saber o que é feito nas funções ListAsArray() e SWExecSql() para poder testar. Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted May 23, 2015 Report Share Posted May 23, 2015 Eu utilizo um método que, para mim, é infalível. Verifico se houve alguma alteração na estrutura. Se houve: • Renomeio a tabela atual para um nome temporário; • Crio a tabela com a nova estrutura; • Importo todos os dados da tabela renomeada para a tabela atual; • Excluo a tabela renomeada. As funções abaixo exemplificam isso: 1 - Exemplo de como crio as tabelas: // Criação da tabela de vendedores aEstr:={} AADD( aEstr ,{ "COD", "N", 10, 0 } ) // Codigo AADD( aEstr ,{ "NOM", "C", 40, 0 } ) // Apelido AADD( aEstr ,{ "END", "C", 40, 0 } ) // Endereço AADD( aEstr ,{ "TEL", "C", 40, 0 } ) // Telefones AADD( aEstr ,{ "FUN", "C", 40, 0 } ) // Cargo / Função AADD( aEstr ,{ "PSW", "C", 32, 0 } ) // Senha (MD5) IF ! SR_ExistTable( "pessoal" ) TRY dbCreate( "pessoal", aEstr, cRDD ) CATCH oErr ShowMsgTray("Erro ao tentar criar a tabela 'pessoal'. Favor verificar as configurações de banco de dados.","Erro") IF FileWrite(".\errorlog\erro.txt", oErr:Description) WAITRUN( GetEnv( "ComSpec" )+" /C NOTEPAD .\errorlog\erro.txt", 0) ENDIF END else lChg := ChkStruct("pessoal", aEstr, oSql, nErr, nPos) ENDIF 2 - Função que criei para modificar a estrutura: STATIC FUNCTION ChkStruct(cTable, aStruct, oSql, nErr, nPos) LOCAL lStrOk := .T., cComm, aNewStr, aOldStr, aChange, aImport, cImport aNewStr := aStruct AADD(aNewStr, {"SR_RECNO", "N", 20, 0}) // SQLRDD acrescenta este campo ao criar a tabela cSay := "Verificando a tabela '"+cTable+"'" oSay:SetText(cSay) oSay:Refresh() IF ! l_Check ; RETURN .T.; ENDIF // Obter a estrutura da tabela atual. nErr := 0 TRY cComm := "SELECT * FROM "+cTable+" LIMIT 1" nErr := oSql:execute( cComm ) oSql:iniFields(.f.) aOldStr := oSql:aFields // Para pegar a estrutura CATCH ShowMsgTray("Não foi possível testar a tabela '"+cTable+"'", "Aviso") SysWait(1) RETURN .T. END TRY // Comparar com a estrutura de aStruct lChangd := .F. aChange := {} aImport := {} cImport := "" TRY FOR nX := 1 TO LEN(aNewStr) // Verifica se foi acrescentado algum campo ou se mudou o tamanho de algum. cFild:=aNewStr[nX,1] cType:=aNewStr[nX,2] cSize:=STRZERO(aNewStr[nX,3], 4) cDeci:=STRZERO(aNewStr[nX,4], 3) nElem := ASCAN(aOldStr, {|aNro| aNro[1] == cFild}) IF nElem > 0 IF cType != aOldStr[nElem,2] .OR. ; cSize != STRZERO(aOldStr[nElem,3], 4) .OR. ; cDeci != STRZERO(aOldStr[nElem,4], 3) lChangd := .T. // Mudou o tamanho de um campo aadd(aChange, {cFild, "Modificou a estrutura"}) ENDIF ELSE lChangd := .T. // Foi removido algum campo aadd(aChange, {cFild, "Campo acrescentado"}) ENDIF NEXT FOR nX := 1 TO LEN(aOldStr) // Verifica se foi excluindo algum compo cFild := aOldStr[nX,1] nElem := ASCAN(aNewStr, {|aNro| aNro[1] == cFild}) IF nElem = 0 lChangd := .T. // Algum campo foi removido aadd(aChange, {cFild, "Campo removido"}) ELSE AADD(aImport, cFild) // Para pegar só os campos que existem nas duas tabelas. ENDIF NEXT IF lChangd // Determinar quais campos serão importados da tabela temporária FOR nX := 1 TO LEN(aImport) IF ! EMPTY(cImport) ; cImport += ", " ; ENDIF cImport += aImport[nX] NEXT ENDIF CATCH ShowMsgTray("Não foi possível testar a tabela '"+cTable+"'", "Aviso") SysWait(1) RETURN .T. END TRY // Excluir a tabela temporária, se existir TRY IF SR_ExistTable( cTable+"_old" ) SR_DropTable(cTable+"_old") ENDIF CATCH oErr ShowMsgTray("Não foi possível excluir a tabela '"+cTable+"_old"+"'", "Erro.") SysWait(1) RETURN .T. END TRY // Renomear a tabela atual para tabela temporária IF lChangd IF ! SR_RenameTable(cTable, cTable+"_old") lChangd := .F. ENDIF ENDIF // Criar tabela atual com a nova estrutura IF lChangd TRY SR_DropTable(cTable) // Já foi renomeada. CATCH oErr END TRY TRY dbCreate(cTable, aStruct, cRDD ) CATCH oErr SR_RenameTable(cTable+"_old", cTable) // Se não conseguir criar a tabela, recuperar a anterior. lChangd := .f. ShowMsgTray("Erro ao tentar modificar a tabela '"+cTable+"'.","Erro") END TRY ENDIF // Importar dados da tabela temporária nErr := 0 IF lChangd cComm := "INSERT INTO "+cTable+" ("+cImport+") "+; "SELECT "+cImport+" FROM "+cTable+"_old" nErr := oSql:execute( cComm ) IF nErr != 0 ShowMsgTray("Erro ao tentar recuperar os dados da tabela '"+cTable+"_old"+"'.","Erro") ENDIF ENDIF // Excluir a tabela temporária TRY SR_DropTable(cTable+"_old") CATCH oErr END TRY RETURN( lStrOk ) Quote Link to comment Share on other sites More sharing options...
Edu Posted May 25, 2015 Author Report Share Posted May 25, 2015 Obrigado Ariston! Vou testar aqui. Abraço. Quote Link to comment Share on other sites More sharing options...
Jorge Andrade Posted May 25, 2015 Report Share Posted May 25, 2015 Eu utilizo um método que, para mim, é infalível. Verifico se houve alguma alteração na estrutura. Se houve: • Renomeio a tabela atual para um nome temporário; • Crio a tabela com a nova estrutura; • Importo todos os dados da tabela renomeada para a tabela atual; • Excluo a tabela renomeada. As funções abaixo exemplificam isso: 1 - Exemplo de como crio as tabelas: // Criação da tabela de vendedores aEstr:={} AADD( aEstr ,{ "COD", "N", 10, 0 } ) // Codigo AADD( aEstr ,{ "NOM", "C", 40, 0 } ) // Apelido AADD( aEstr ,{ "END", "C", 40, 0 } ) // Endereço AADD( aEstr ,{ "TEL", "C", 40, 0 } ) // Telefones AADD( aEstr ,{ "FUN", "C", 40, 0 } ) // Cargo / Função AADD( aEstr ,{ "PSW", "C", 32, 0 } ) // Senha (MD5) IF ! SR_ExistTable( "pessoal" ) TRY dbCreate( "pessoal", aEstr, cRDD ) CATCH oErr ShowMsgTray("Erro ao tentar criar a tabela 'pessoal'. Favor verificar as configurações de banco de dados.","Erro") IF FileWrite(".\errorlog\erro.txt", oErr:Description) WAITRUN( GetEnv( "ComSpec" )+" /C NOTEPAD .\errorlog\erro.txt", 0) ENDIF END else lChg := ChkStruct("pessoal", aEstr, oSql, nErr, nPos) ENDIF 2 - Função que criei para modificar a estrutura: STATIC FUNCTION ChkStruct(cTable, aStruct, oSql, nErr, nPos) LOCAL lStrOk := .T., cComm, aNewStr, aOldStr, aChange, aImport, cImport aNewStr := aStruct AADD(aNewStr, {"SR_RECNO", "N", 20, 0}) // SQLRDD acrescenta este campo ao criar a tabela cSay := "Verificando a tabela '"+cTable+"'" oSay:SetText(cSay) oSay:Refresh() IF ! l_Check ; RETURN .T.; ENDIF // Obter a estrutura da tabela atual. nErr := 0 TRY cComm := "SELECT * FROM "+cTable+" LIMIT 1" nErr := oSql:execute( cComm ) oSql:iniFields(.f.) aOldStr := oSql:aFields // Para pegar a estrutura CATCH ShowMsgTray("Não foi possível testar a tabela '"+cTable+"'", "Aviso") SysWait(1) RETURN .T. END TRY // Comparar com a estrutura de aStruct lChangd := .F. aChange := {} aImport := {} cImport := "" TRY FOR nX := 1 TO LEN(aNewStr) // Verifica se foi acrescentado algum campo ou se mudou o tamanho de algum. cFild:=aNewStr[nX,1] cType:=aNewStr[nX,2] cSize:=STRZERO(aNewStr[nX,3], 4) cDeci:=STRZERO(aNewStr[nX,4], 3) nElem := ASCAN(aOldStr, {|aNro| aNro[1] == cFild}) IF nElem > 0 IF cType != aOldStr[nElem,2] .OR. ; cSize != STRZERO(aOldStr[nElem,3], 4) .OR. ; cDeci != STRZERO(aOldStr[nElem,4], 3) lChangd := .T. // Mudou o tamanho de um campo aadd(aChange, {cFild, "Modificou a estrutura"}) ENDIF ELSE lChangd := .T. // Foi removido algum campo aadd(aChange, {cFild, "Campo acrescentado"}) ENDIF NEXT FOR nX := 1 TO LEN(aOldStr) // Verifica se foi excluindo algum compo cFild := aOldStr[nX,1] nElem := ASCAN(aNewStr, {|aNro| aNro[1] == cFild}) IF nElem = 0 lChangd := .T. // Algum campo foi removido aadd(aChange, {cFild, "Campo removido"}) ELSE AADD(aImport, cFild) // Para pegar só os campos que existem nas duas tabelas. ENDIF NEXT IF lChangd // Determinar quais campos serão importados da tabela temporária FOR nX := 1 TO LEN(aImport) IF ! EMPTY(cImport) ; cImport += ", " ; ENDIF cImport += aImport[nX] NEXT ENDIF CATCH ShowMsgTray("Não foi possível testar a tabela '"+cTable+"'", "Aviso") SysWait(1) RETURN .T. END TRY // Excluir a tabela temporária, se existir TRY IF SR_ExistTable( cTable+"_old" ) SR_DropTable(cTable+"_old") ENDIF CATCH oErr ShowMsgTray("Não foi possível excluir a tabela '"+cTable+"_old"+"'", "Erro.") SysWait(1) RETURN .T. END TRY // Renomear a tabela atual para tabela temporária IF lChangd IF ! SR_RenameTable(cTable, cTable+"_old") lChangd := .F. ENDIF ENDIF // Criar tabela atual com a nova estrutura IF lChangd TRY SR_DropTable(cTable) // Já foi renomeada. CATCH oErr END TRY TRY dbCreate(cTable, aStruct, cRDD ) CATCH oErr SR_RenameTable(cTable+"_old", cTable) // Se não conseguir criar a tabela, recuperar a anterior. lChangd := .f. ShowMsgTray("Erro ao tentar modificar a tabela '"+cTable+"'.","Erro") END TRY ENDIF // Importar dados da tabela temporária nErr := 0 IF lChangd cComm := "INSERT INTO "+cTable+" ("+cImport+") "+; "SELECT "+cImport+" FROM "+cTable+"_old" nErr := oSql:execute( cComm ) IF nErr != 0 ShowMsgTray("Erro ao tentar recuperar os dados da tabela '"+cTable+"_old"+"'.","Erro") ENDIF ENDIF // Excluir a tabela temporária TRY SR_DropTable(cTable+"_old") CATCH oErr END TRY RETURN( lStrOk ) Ariston Boa noite Me corrija se eu estiver enganando e já de antemão, desculpe a minha ignorância, a forma do seu método de alteração, está mais voltada/semelhante as alterações em DBF (Offline), enquanto a anterior está para SQL, ou seja, enquanto a anterior pode ser executada em tempo real inclisive com a possibilidade da tabela em uso, enquanto o seu sofrerá efeito somente se o sistema estiver inoperante ou a tabela não estiver em uso. []s, Quote Link to comment Share on other sites More sharing options...
Edu Posted May 25, 2015 Author Report Share Posted May 25, 2015 Ariston, Testei aqui e não funcionou. Quote Link to comment Share on other sites More sharing options...
Ariston Santos Posted May 25, 2015 Report Share Posted May 25, 2015 Realmente é bem parecido com o método que uso para alterar estrutura de DBF, embora adaptada para SQLRDD e só funciona com bancos de dados relacionais (MySQL, Firebird, etc) Ainda não testei em um momento que outros usuários estivessem usando as tabelas. Carece testar e fazer as devidas correções em caso de erro. Qualquer modificação, favor postar aqui. Agradeço. Edu, favor entrar em contato por email para eu poder ajudar melhor: airston.ap@hotmail.com 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.