Alteração do caminho do banco em runtime
Boa tarde a todos, gostaria de saber como faço para alterar a propriedade connectionName e alterar o banco.no meu pc funciona normal, entretanto na maquina que precisa rodar a aplicação não consigo, apresentando erro.a propriedade LoadParamsOnConnect ja esta ativada.ja tentei arquivo ini entretanto.. apresenta erro tambem,porem não sei muito bem como montar um arquivo e nem como carrega-lotentei da seguinte mandeira:
Servercliente.SQLCliente.Connected:=false;ServerCliente.SQLCliente.Params.Values['drivername']:='FIREBIRD';ServerCliente.SQLCliente.Params.Values['blobsize']:='-1';ServerCliente.SQLCliente.Params.Values['commitretain']:='False';ServerCliente.SQLCliente.Params.Values['localecode']:='0000';ServerCliente.SQLCliente.Params.Values['password']:='masterkey';ServerCliente.SQLCliente.Params.Values['rolename']:='RoleName';ServerCliente.SQLCliente.Params.Values['sqldialect']:='3';ServerCliente.SQLCliente.Params.Values['isolationlevel']:='ReadCommitted';ServerCliente.SQLCliente.Params.Values['user_name']:='sysdba';ServerCliente.SQLCliente.Params.Values['waitonlocks']:='True';ServerCliente.SQLCliente.Params.Values['trim char']:='False';ServerCliente.SQLCliente.Params.Values['Database']:='banco1.FDB';
alguem tem alguma ideia?estou usando o delphi2010grato a todos,
Servercliente.SQLCliente.Connected:=false;ServerCliente.SQLCliente.Params.Values['drivername']:='FIREBIRD';ServerCliente.SQLCliente.Params.Values['blobsize']:='-1';ServerCliente.SQLCliente.Params.Values['commitretain']:='False';ServerCliente.SQLCliente.Params.Values['localecode']:='0000';ServerCliente.SQLCliente.Params.Values['password']:='masterkey';ServerCliente.SQLCliente.Params.Values['rolename']:='RoleName';ServerCliente.SQLCliente.Params.Values['sqldialect']:='3';ServerCliente.SQLCliente.Params.Values['isolationlevel']:='ReadCommitted';ServerCliente.SQLCliente.Params.Values['user_name']:='sysdba';ServerCliente.SQLCliente.Params.Values['waitonlocks']:='True';ServerCliente.SQLCliente.Params.Values['trim char']:='False';ServerCliente.SQLCliente.Params.Values['Database']:='banco1.FDB';
alguem tem alguma ideia?estou usando o delphi2010grato a todos,
Bruno Mendonça
Curtidas 0
Respostas
Marco Salles
02/02/2011
Iamgine que vc tenha um Arquivo Ini com esta estrtura ...
Gravado no diretorio da Aplicação com o nome de Temp.ini
drivername=FIREBIRD
blobsize=-1
commitretain=False
database=C:\zPodeApagar\Alv\db.ini
localecode=0000
Password=masterkey
rolename=RoleName
sqldialect=3
isolationlevel=ReadCommitted
user_name=sysdba
waitonlocks=True
trim char=False
port=3155
communicationprotocol=tcp
Podemos ,utilizando entre outros meios , um TString para ler qq propriedade deste Arquivo INI e tb Modifica-lo Perceba o codigo abaixo e adapte á sua necessidade
blobsize=-1
commitretain=False
database=C:\zPodeApagar\Alv\db.ini
localecode=0000
Password=masterkey
rolename=RoleName
sqldialect=3
isolationlevel=ReadCommitted
user_name=sysdba
waitonlocks=True
trim char=False
port=3155
communicationprotocol=tcp
Podemos ,utilizando entre outros meios , um TString para ler qq propriedade deste Arquivo INI e tb Modifica-lo Perceba o codigo abaixo e adapte á sua necessidade
var
Lista:TStrings;
begin
Lista:=TStringList.Create;
lista.LoadFromFile('temp.ini');
try
showmessage(Lista.Values['database']); // so a título de demostrativo
if OpenDialog1.Execute then
begin
OpenDialog1.FileName;
Lista.Values['database']:=OpenDialog1.FileName; //com esta propriedade vc alter qq propriedade
Lista.SaveToFile('temp.ini');
end;
finally
lista.Free;
end;
Observação .. Veja que meu arquivo tem o Sinal de Igualdade separando o Campo dp Atributo
Caso necessite um Outro tipo de separação , acredito não ser ocaso , basta definir a property
lista.NameValueSeparator := 'Ao Novo caracter de Separação' *** So para constar
No caso do TStrings o Default é o sinal de Igualdade
GOSTEI 0
Bruno Mendonça
02/02/2011
Marco, obrigado pela ajuda, a sua informação foi extremamente util,entretanto, como faço agora para o sistema ler este arquivo, config.ini que ja esta pre configuradoe alterar em tempo de execução.vou tentar explicar melhor.tenho uma aplicação simples que funciona em multi camadas,e gostaria de rodar dois servidores, so que sem dar start automatico, e sim pressionando um botao ondeseleciona o banco no sqlconnection, seta a porta do servidor e da start no mesmo.
Procedure.botao1
Procedure.botao2
eu fiz desta maneira em meu computador e deu certo, so que no servidor não.obrigado novamente...
Procedure.botao1
Servercliente.SQLCliente.Connected:=false;ServerCliente.SQLCliente.ConnectionName:='BANCO';ServerConexoes.DSTCPServerTransport1.Port:=235;Servercliente.SQLCliente.Connected:=true;ServerConexoes.DSServer1.Start;
Procedure.botao2
Servercliente.SQLCliente.Connected:=false;ServerCliente.SQLCliente.ConnectionName:='BANCO2';ServerConexoes.DSTCPServerTransport1.Port:=240;Servercliente.SQLCliente.Connected:=true;ServerConexoes.DSServer1.Start;
eu fiz desta maneira em meu computador e deu certo, so que no servidor não.obrigado novamente...
GOSTEI 0
Marco Salles
02/02/2011
No post original ( primeiro post ) vc não comentiu que estava utilizando Arquitetura Multi Camadas
e tb não mencionou qual a tecnologia que vc esta empregando ??? DataSnao ??? qual ???
GOSTEI 0
Bruno Mendonça
02/02/2011
desculpe pela falta de informação postada,estou usando datasnap..de certa forma consegui resolver o problema, peguei o arquivo dbxconnections.ini e coloquei junto com o executavel, desta forma consegui fazer como descrevi acima,a forma que estou usando para alternar entre os bancos no cliente é trocando a porta de comunicação.entretanto, ele sempre acessa o mesmo banco de dados de cliente, mesmo o servidor indicando que ele ira acessar outro banco. como no print
mesmo alterando as portas no cliente ele somente conecta-se no banco Mastertech, um é porta 240 e o outro é 235e no server mostra que a porta 240 vai pro mmbom isto acho que é da forma mais explicagrato pela atençao e pela ajuda
mesmo alterando as portas no cliente ele somente conecta-se no banco Mastertech, um é porta 240 e o outro é 235e no server mostra que a porta 240 vai pro mmbom isto acho que é da forma mais explicagrato pela atençao e pela ajuda
GOSTEI 0
Marco Salles
02/02/2011
a forma que estou usando para alternar entre os bancos no cliente é trocando a porta de comunicação.
entretanto, ele sempre acessa o mesmo banco de dados de cliente, mesmo o servidor indicando que ele ira acessar outro banco
Mas olhando olhando o print , parace se tratar de dois bancos diferentes , pelo menos ele tem registros diferentes .
Eu tb faria o que vc esta fazendo , que é trocar a porta de comunicação no Cliente para se comunicar com
este ou aquele servidor ... Apos trocar a porta vc da um SQLConnection1.Open; novamente no Cliente ????
Agora pq dois Servidores para dois Bancos ??? e Não um Servidor para este dois Bancos ???
GOSTEI 0
Bruno Mendonça
02/02/2011
bom é que eu nao tenho a menor ideia de somo seria 1 servidor para dois bancos de dados..sim fecho todas as conexoes, e depois que altero porta e connectionname, abro novamenteo sqlconnection e do start no server..nos programas servidores é feito a alternância, entretanto o cliente, mesmo alterando as portase fechando e abrindo o sqlconnection não reconhece o outro banco de registro. ele me retorna apenas o da mastertech conforme o print, mesmo que eu feche, altere a porta para da mmcelulares, ele continua trazendo os registros da mastertech.novamente obrigado pela ajuda
GOSTEI 0
Marco Salles
02/02/2011
bom é que eu nao tenho a menor ideia de somo seria 1 servidor para dois bancos de dados.
Para ser sincero tb nunca fiz isto ... Mas no servido na propriedade params dele é so vc carregar o
Arquivo Ini que contem os parametros da nova configração
Por exemplo
;;Para o Banco A
if BancoA then
Conexao.Params.LoadFromStream(AquivoIniBancoA)
else
Conexao.Params.LoadFromStream(AquivoIniBancoB)
Claro que tem que ser feito com o Conexao Desativado
Bem , é uma solução acredito , se a base de dados estiver a mesmoa estrutura .. Acredito olhando o Print ser este o Caso
Outra pergunta .. Vc esta Rodando estes servidores como Aplicação ????
GOSTEI 0
Bruno Mendonça
02/02/2011
o firebird esta configurado como servidor. se for a isto que você se refere quando fala se estou rodando como servidor. .e estou fazendo isto, fecho a conexao, do load no arquivo.e depois abro..no print se voce olhar se eu apertar o botao eu consigo alternar os servidores, e no grid aparece para mim qual esta rodando, acho que o problema esta na aplicação cliente ...e não estou conseguindo identificar..
GOSTEI 0
Marco Salles
02/02/2011
O Servidor que eu falo é o servidor DataSnap
Ele esta como Aplicação ???? Parece que sim
Vc não entendeu o que eu disse no ultimo post . Pode ser que da certo. Pelo menos a logica é para dar certo
Se vc Alternar entre o Banco no Servidor o Client Vai Receber os Dados deste Banco .. Estou falando na situação que estes bancos tenham a mesma estrutura
No servidor em um Botão
Fecha a conexao
Testa se que ler o Arquvo Ini do Banco A
ou se quer ler o Arquivo Ini do Banco B
Abre a conexão
Claro que a principio esses dois Arquivos Ini tem que estar no Diretorio da Aplicação Servidora
entendeu ?? Testou ?? não concorda ???
GOSTEI 0
Bruno Mendonça
02/02/2011
efetuei o teste que voce falou, e o banco tem a mesma estrutura sim.pelo que pude perceber, quando executo a aplicação com o banco mmcelulares parametrizado, o cliente independente do que eu faça ele somente reconhece somente o banco mm mesmo alterando a porta, e quando executo a aplicacação tendo parametrizando inicialmente o da mastertech ocorre o mesmo,
GOSTEI 0
Marco Salles
02/02/2011
Fiz ums teste aqui , e funcionou perfeito .. Um servidor Alternando entre dois Bancos . Funcionou perfeitamente .. Eu escolho qual o Banco atraves do Cliente
Fiz assim no cliente
procedure TForm8.Button1Click(Sender: TObject);
begin
case RadioGroup1.ItemIndex of
0:DmCliente.SqlServerMethod1.Params[0].AsString:='Employee';
1:DmCliente.SqlServerMethod1.Params[0].AsString:='Contatos';
end;
DmCliente.SqlServerMethod1.ExecuteMethod; if DmCliente.SqlServerMethod1.Params[1].AsBoolean then
begin
DmCliente.ClientDataSet1.Close;
DmCliente.ClientDataSet1.Open;
end;
end; Passo para o SqlServerMethod1 ( um método no Servidor ) qual o Banco que eu Quero Este Metodo esta assim No Servidor function TServerMethods1.AternarBanco(NomeBanco: String): Boolean;
const
Caminho = 'C:\Users\Marco Salles\Documents\RAD Studio\Projects\DataSnapServidorComDoisBancos\Servidor\'; {Caminho onde esta meus Arquivos INI .. Tenho dois o Employee.INI e o Contatos.Ini}
var
StrFileName:String;
begin
conexao.Close;
SQLQuery1.SQL.Clear;
case AnsiIndexStr(UpperCase(NomeBanco), ['EMPLOYEE', 'CONTATOS']) of
0:begin
StrFileName:='Employee.Ini'; // Novo Sql para conectar em uma Tabela do Banco EMPLOYEE
SQLQuery1.SQL.Add('Select * From Employee');
end;
1:begin
StrFileName:='Contatos.ini'; // Novo Sql para conectar em uma Tabela do Banco CONTATOS
SQLQuery1.SQL.add('Select * From CONTATOS');
end;
end;
Conexao.Params.Clear; //Carrego o Parametro da conexão
conexao.Params.LoadFromFile(caminho+StrFileName);
try //testo se esta tudo bem
conexao.Open; //se tiver retorna boolean=True , para o Metodo do cliente que envovou este método no servidor
result:=True;
except //se algo der errado , retorno False para o método do Cliente que chamou este método no Servidor
result:=false
end;
end;
Como as tabelas tem a mesma estrutura muita coisa pode ser reaproveitada no servidor , todos os tfields do clientDataSet por exemplo .. Como o meu caso foi so demostrativo , so carrego o clientDataSet do Cliente em um DbGrid , utilizando o DataSouce
begin
case RadioGroup1.ItemIndex of
0:DmCliente.SqlServerMethod1.Params[0].AsString:='Employee';
1:DmCliente.SqlServerMethod1.Params[0].AsString:='Contatos';
end;
DmCliente.SqlServerMethod1.ExecuteMethod; if DmCliente.SqlServerMethod1.Params[1].AsBoolean then
begin
DmCliente.ClientDataSet1.Close;
DmCliente.ClientDataSet1.Open;
end;
end; Passo para o SqlServerMethod1 ( um método no Servidor ) qual o Banco que eu Quero Este Metodo esta assim No Servidor function TServerMethods1.AternarBanco(NomeBanco: String): Boolean;
const
Caminho = 'C:\Users\Marco Salles\Documents\RAD Studio\Projects\DataSnapServidorComDoisBancos\Servidor\'; {Caminho onde esta meus Arquivos INI .. Tenho dois o Employee.INI e o Contatos.Ini}
var
StrFileName:String;
begin
conexao.Close;
SQLQuery1.SQL.Clear;
case AnsiIndexStr(UpperCase(NomeBanco), ['EMPLOYEE', 'CONTATOS']) of
0:begin
StrFileName:='Employee.Ini'; // Novo Sql para conectar em uma Tabela do Banco EMPLOYEE
SQLQuery1.SQL.Add('Select * From Employee');
end;
1:begin
StrFileName:='Contatos.ini'; // Novo Sql para conectar em uma Tabela do Banco CONTATOS
SQLQuery1.SQL.add('Select * From CONTATOS');
end;
end;
Conexao.Params.Clear; //Carrego o Parametro da conexão
conexao.Params.LoadFromFile(caminho+StrFileName);
try //testo se esta tudo bem
conexao.Open; //se tiver retorna boolean=True , para o Metodo do cliente que envovou este método no servidor
result:=True;
except //se algo der errado , retorno False para o método do Cliente que chamou este método no Servidor
result:=false
end;
end;
Como as tabelas tem a mesma estrutura muita coisa pode ser reaproveitada no servidor , todos os tfields do clientDataSet por exemplo .. Como o meu caso foi so demostrativo , so carrego o clientDataSet do Cliente em um DbGrid , utilizando o DataSouce
GOSTEI 0
Bruno Mendonça
02/02/2011
Marcos, eu efetuando o load do arquivo, exemplo master.iniele ta um erro dizendo que o banco de dados é invalido,entretanto, no arquivo esta certo.
[MASTER]drivername=FIREBIRDblobsize=-1commitretain=Falselocalecode=0000password=masterkeyrolename=RoleNamesqldialect=3isolationlevel=ReadCommitteduser_name=sysdbawaitonlocks=Truetrim char=FalseDatabase=C:\SERVIDOR\MASTERTECH\BANCOMASTERTECH.FDB
so que ele fala que o banco que ele tentou localizar é um chamado cliente.gdbque eu nem sei da onde saiu isto.
[MASTER]drivername=FIREBIRDblobsize=-1commitretain=Falselocalecode=0000password=masterkeyrolename=RoleNamesqldialect=3isolationlevel=ReadCommitteduser_name=sysdbawaitonlocks=Truetrim char=FalseDatabase=C:\SERVIDOR\MASTERTECH\BANCOMASTERTECH.FDB
so que ele fala que o banco que ele tentou localizar é um chamado cliente.gdbque eu nem sei da onde saiu isto.
GOSTEI 0
Deivison Melo
02/02/2011
Segue rotina para leitura do caminho do banco de dados em tempo de execução:
/**************************************************************************************************************/
/*DataModule Principal - (inicio)*/
No evento OnCreate do DataModule fiz o seguinte: begin
if not FileExists('sga.ini') then
// Se não existe chamo um formulário para gravar o caminho do banco
ChamaForm(TfrmConfiguracao, frmConfiguracao)
else
begin
try
with ConexaoDB do
begin
Connected := False;
connectionname := 'PortoBello';
drivername := 'interbase';
getdriverfunc := 'getSQLDriverINTERBASE';
libraryname := 'dbexpint.dll';
params.clear;
params.add('drivername=interbase');
params.add('database= ' + LerInI('sga.ini', 'DB', 'caminho'));
params.add('rolename=rolename');
params.add('user_name=' + LerInI('sga.ini', 'DB', 'usuario'));
params.add('password=' + LerInI('sga.ini', 'DB', 'senha'));
params.add('servercharset=');
params.add('sqldialect=3');
params.add('blobsize=-1');
params.add('commitretain=false');
params.add('waitonlocks=true');
params.add('errorresourcefile=');
params.add('localecode=0000');
params.add('interbase transisolation=readcommited');
params.add('trim char=false');
vendorlib := 'gds32.dll';
Connected := true;
end;
except
raise Exception.Create('Verifique se as configurações do arquivo "sga.ini" estão corretas!');
end;
end; /*DataModule Principal - (fim)*/ /**************************************************************************************************************/
/*Procedure GravaIni - (inicio)*/ //Procedure para gravar arquivo ini usado no login procedure GravaIni(Arquivo, Sessao, Subsessao, valor: string);
var
ArqIni: TIniFile;
begin
ArqIni := TIniFile.Create(ExtractFilePath(ParamStr(0)) + Arquivo);
try
ArqIni.WriteString(Sessao, Subsessao, valor);
finally
FreeAndNil(ArqIni);
end;
end; /*Procedure GravaIni - (inicio)*/
/**************************************************************************************************************/
/*Function GravaIni - (inicio)*/
//Funcao para ler arquivo ini usado no login function LerIni(Arquivo, Sessao, Subsessao: string): string;
var
ArqIni: TIniFile;
sDirAplicacao: string;
begin
sDirAplicacao := ExtractFilePath(ParamStr(0));
ArqIni := TIniFile.Create(ExtractFilePath(ParamStr(0)) + Arquivo);
try
Result := ArqIni.ReadString(Sessao, Subsessao, '');
finally
FreeAndNil(ArqIni);
end;
end;
/*Procedure GravaIni - (fim)*/
/**************************************************************************************************************/
/**************************************************************************************************************/
/*DataModule Principal - (inicio)*/
No evento OnCreate do DataModule fiz o seguinte: begin
if not FileExists('sga.ini') then
// Se não existe chamo um formulário para gravar o caminho do banco
ChamaForm(TfrmConfiguracao, frmConfiguracao)
else
begin
try
with ConexaoDB do
begin
Connected := False;
connectionname := 'PortoBello';
drivername := 'interbase';
getdriverfunc := 'getSQLDriverINTERBASE';
libraryname := 'dbexpint.dll';
params.clear;
params.add('drivername=interbase');
params.add('database= ' + LerInI('sga.ini', 'DB', 'caminho'));
params.add('rolename=rolename');
params.add('user_name=' + LerInI('sga.ini', 'DB', 'usuario'));
params.add('password=' + LerInI('sga.ini', 'DB', 'senha'));
params.add('servercharset=');
params.add('sqldialect=3');
params.add('blobsize=-1');
params.add('commitretain=false');
params.add('waitonlocks=true');
params.add('errorresourcefile=');
params.add('localecode=0000');
params.add('interbase transisolation=readcommited');
params.add('trim char=false');
vendorlib := 'gds32.dll';
Connected := true;
end;
except
raise Exception.Create('Verifique se as configurações do arquivo "sga.ini" estão corretas!');
end;
end; /*DataModule Principal - (fim)*/ /**************************************************************************************************************/
/*Procedure GravaIni - (inicio)*/ //Procedure para gravar arquivo ini usado no login procedure GravaIni(Arquivo, Sessao, Subsessao, valor: string);
var
ArqIni: TIniFile;
begin
ArqIni := TIniFile.Create(ExtractFilePath(ParamStr(0)) + Arquivo);
try
ArqIni.WriteString(Sessao, Subsessao, valor);
finally
FreeAndNil(ArqIni);
end;
end; /*Procedure GravaIni - (inicio)*/
/**************************************************************************************************************/
/*Function GravaIni - (inicio)*/
//Funcao para ler arquivo ini usado no login function LerIni(Arquivo, Sessao, Subsessao: string): string;
var
ArqIni: TIniFile;
sDirAplicacao: string;
begin
sDirAplicacao := ExtractFilePath(ParamStr(0));
ArqIni := TIniFile.Create(ExtractFilePath(ParamStr(0)) + Arquivo);
try
Result := ArqIni.ReadString(Sessao, Subsessao, '');
finally
FreeAndNil(ArqIni);
end;
end;
/*Procedure GravaIni - (fim)*/
/**************************************************************************************************************/
GOSTEI 0