Atualizar Estrutura do Banco de Dados Automaticamente

Imaginem que se tem um único sistema multi-empresa, e ele está em produção com mais de 20 banco de dados, um para cada cliente, aí você precisa incluir um novo campo ou uma nova tabela, como fazer ??

Em Delphi eu conseguia checar, assim que fosse feita a conexão com o banco de dados, se aquela tabela estava ou não atualizada, e se não estivesse fazia isso automaticamente, sem precisar fazer um script e atualizar manualmente cada base de dados de cada cliente.

Com o SC, como fazer isso ?

Boa pergunta…

Se o SC trabalhasse com Persistência de banco de dados seria capaz. Mas… em fim!

Só uma ideia

Se deixar na base de dados uma tabela ou campo contendo a versão da base de dados, com isso poderia verificar no login por exemplo com uma consulta e direcionar para uma aplicação de atualização de base se necessário.

Acredito que esta questão é de decisão de projeto, e assumir os riscos ter soluções para contornar.

Temos projetos multi-empresas e o banco está definido para todos os clientes no mesmo.

No SC… e está funcionando.

Forte abraço à todos

O Haroldo já faz isso a 1000 anos, mas ele é o MESTRE dos MAGOS. heehe

Eu prefiro fazer um banco só, usando um WHERE CodigoEmpresaID

Uma idéia seria, mantenha no servidor uma pasta contendo a versao do banco e dentro dela os scripts de atualização, ao entrar na aplicação você checa qual a versão do seu banco, caso tenha uma pasta com uma versão superior, vc entra nela, processa o script que estiver la dentro e atualiza a versão de seu banco, faço algo assim com aplicações java desktop para atualizar na base dos clientes que é local e funciona 100%

Essa coisa de manter um banco único para todos os clientes por um lado é bom, mas eu tenho receio de isso se tornar muito pesado com o passar do tempo. E uma eventual bronca nesse banco todos os clientes seriam afetados. Até usaria isso se fosse um cliente com várias filiais, mas para clientes distintos eu acho temerário, prefiro separar fisicamente os BDs.

Um jeito simples de se fazer:

Banco do Cliente:
Tabela Parametros: Id_Ult_instr_SQL

Banco Mestre:
Tabela: SQL_Instrucoes (id (int, autoincremento), instrucao(Text))

App Login:

  • Verifica se eh o primeiro login do dia

  • sc_lookup(ds,“Select Id_Ult_instr_SQL from Parametros”)

  • sc_select(ds, “Select instrucao, id from SQL_Instrucoes where id > $_Id_Ult_instr_SQL”, “Conexao_Mestre”)

. No loop: sc_exec_sql($_instrucao); $_Id_Ult_instr_SQL=$ds[0][1];

  • Após execução do loop: sc_exec_sql(“update Parametros set Id_Ult_instr_SQL=$_Id_Ult_instr_SQL”)

*Vai precisar de um formulário para alimentar as instruções sql na tabela SQL_Instrucoes.
*Todo e qualquer alteração em banco o workbench exibe o sql executado copie e cole no formulário.

2 Curtidas

Concordo.

Taí, gostei… uma boa maneira de controlar as versões de bancos separados… vou pensar!
Apesar de que hoje em dia os bancos são muito bons, quando você tem uma boa modelagem.

Mestre Haroldo,

Gostei. Só não entendi o por que é ncessário checar se é o primeiro login do dia, não vai ser feito independentemente disso, ou melhor, não vai ser processada o script assim que o sistema detectar nova atualização, e isso não será sempre no primeiro login naquele banco especfífico ???

Eh que eu costumo verificar se é o primeiro login do dia, se tem atualização a realizar, travo os demais usuários a se logarem executo as atualizações depois libero, para não ficar fazendo atualização com usuários operando o sistema.

E sempre programo as atualizações e acumulo várias também, geralmente uma vez por semana são executadas, mas isso eh como eu faço, cada um pode atualizar da forma que desejar.

Se eu gravar as atualizações durante o dia essas só serão executadas no dia seguinte.

Eu tenho uma dúvida sobre este modo, me desculpem a pergunta, mas nunca fiz assim.

E as conexões? Vai ter uma para clada banco ou pode-se mudar a conexão dinamicamente?

a conexão padrão é a do banco de dados do cliente (muda dinamicamente no login).

a conexão fixa é a conexão mestre.

Geralmente se você tem vários bancos no mesmo servidor a conexão é uma só. Pelo menos no meu servidor é assim! Tenho vários bancos com uma única conexão. (Conexão que digo seria o mesmo Login e Password)

Então pelo que entendi, se eu tenho vários bancos na mesma *instância não preciso ter no SC uma conexão registrada para cada cliente?

*Um servidor pode ter um SQL Server, mas, com instâncias diferentes (administradores, usuários, regras, etc)

Estou tentando implementar essa rotina mas estou com problemas na execução da macro sc_exec_sql.

A minha rotina está feita dentro da aplicação de login, depois de setar a conexão através do sc_change_conection, eu verifico a versão do banco de dados do cliente e comparo a a última versão existente numa tabela onde eu armazeno os scripts de atualização.

Ocorre que quando mando executar o script através da macro sc_exec_sql informando além do script a conexão do cliente, que não é a mesma da aplicação login, ele dá um erro, a sintaxe que estou usando é exatamente esta:

sc_exec_sql($script,$conexao);

onde, a variável $script é o comando sql para ser executado e $conexao é o nome da conexão do cliente.

Só que quando executo isso, o SC me dá a mensagem de erro dizendo que a vírgula ali que separa uma variável da outra, não é esperada.

Que diabos eu estou fazendo de errado, ou isso é mais um bug da nossa versão 8 do SC ?

Tenta fazer essa conexão sem ser pela macro pra ver se funciona! Exemplo:

// Primeiro servidor
$banco1 = mysql_connect(‘127.0.0.1’, ‘root’, ‘’);
mysql_select_db(‘banco’, $banco1);

// Segundo servidor
$banco2 = mysql_connect('127.0.0.2', 'root', '');
mysql_select_db('banco', $banco2);

// Terceiro servidor
$banco3 = mysql_connect('127.0.0.3', 'root', '');
mysql_select_db('banco', $banco3);

// ...
// Consulta no 1° banco
$sql1 = mysql_query('SELECT * FROM tabela', $banco1);
// ... processa os dados ...

// Consulta no 2° banco
$sql2 = mysql_query('SELECT * FROM tabela', $banco2);
// ... processa os dados ...

// Consulta no 3° banco
$sql3 = mysql_query('SELECT * FROM tabela', $banco3);
// ... processa os dados ...

Etc… Etc…

Ronaldo, pode ser que haja concatenação de strings na variável $script e a macro esteja se perdendo. Se não houver erro na variável $script, você pode tentar executá-la assim c_exec_sql("$script",$conexao); ou como um campo do controle:c_exec_sql({script},$conexao) ;