Fórum Ajuda com logica e BD #348660
07/11/2007
0
Bem, abaixo esta o codigo fonte de um programinha que to fazendo. Basicamente, ele le uma variavel de um arquivo .INI, que e o caminho do banco de dados ANTIGO, e em seguida, ele verifica se e possivel migrar os dados do banco de dados ANTIGO pro NOVO, porq outras versoes desse software nao vao ser suportadas. Entao ele pega o nome da tabela, do campo, o tipo do campo, e em seguida entra no banco de dados novo e faz a mesma coisa, e grava em um TXT. Entao o formato seria:
NomedaTabelaANTIGA:CampoANTIGO:TipoANTIGO:CampoNOVO:Tabela
Entao, estou tendo uns probleminhas...
1. Toda vez que vou executar, ele da um erro com o label ´Transaction is active´. Nao entendi o teor desse erro, tentei debugar e nada.
2. Bem, como voces podem ver, o que eu estou fazendo e criando um laco for, e ele se repete de acordo com o numero de elementos no TStringList CamposBDANTIGO. Mas o problema, tambem, e que o TStringList CamposBDANTIGO contem um numero de elementos diferente do TStringList CamposBDNOVO. Como criar mais um laco for, ou dentro do mesmo, pra conseguir colocar o valor dos campos do lado?
procedure TFPrincipal.LerIni(var CaminhoBDANTIGO: string); // Procedure para ler o arquivo INI. // Variaveis globais usadas sao: // CaminhoBDANTIGO : String; // CaminhoArquivoIni : TIniFile; begin CaminhoArquivoIni := TIniFile.Create(´C:\Arquivos de Programas\Notoriun\Laudo Facil\consultorio.ini´); //Atribuindo o caminho a variavel. CaminhoBDANTIGO := CaminhoArquivoIni.ReadString(´BancoDados´, ´local_Text´, CaminhoBDANTIGO); //Assimilando o valor a Variavel CaminhoDBANTIGO. CaminhoArquivoIni.Free; //Liberando... if (CaminhoBDANTIGO = ´´) then //Caso nao ache o Local_text... begin RichLog.Lines.Add(´Banco de dados nao encontrado no diretorio padrao.´); Application.CreateForm(TFOpenBox, FOpenBox); FopenBox.Show(); end else Shape0.Brush.Color := clgreen; RichLog.Lines.Add(´locahost:´+CaminhoBDANTIGO); //Coloca o valor no Label. ConectarBD(); end; procedure TFPrincipal.DicionarioDeDados(); // Esta procedure tem como objetivo criar um arquivo de texto em aonde o migrador esta sendo executado e, em seguida, // escrever o nome dos campos da tabela antiga e o nome da tabela, tal como tipo do campo, etc. var ArquivoTexto : TextFile; //Declarando var do arquivo de texto. CamposBDANTIGO_Temp : TStringList; //Declarando a variavel que armazenara o nome dos campos, temporariamente. TabelasBDANTIGO_Temp : TStringList; //Declarando a variavel que armazenara o nome dos campos, temporariamente. CamposBDNOVO_Temp : TStringList; //Declarando a variavel que vai armazenar o nome dos campos do Banco novo. TabelasBDNOVO_Temp : TStringList; //Declarando a variavel que armazenara o nome das tabelas. I,J,K: Integer; //Declarando o contador. begin CamposBDANTIGO_Temp := TStringList.Create; TabelasBDANTIGO_Temp := TStringList.Create; CamposBDNOVO_Temp := TStringList.Create; TabelasBDNOVO_Temp := TStringList.Create; AssignFile(ArquivoTexto, ´C:\BD.txt´); Richlog.Lines.Add(´Arquivo do dicionario de dados criado.´); Rewrite(ArquivoTexto); DataBaseANTIGO.GetTableNames(TabelasBDANTIGO_Temp, FALSE); // Armazenando o nome das tabelas na variavel. DataBaseNOVO.GetTableNames(TabelasBDNOVO_Temp, FALSE); // Armazenando o nome das tabelas na variavel. for I := 0 to TabelasBDANTIGO_Temp.Count - 1 do Begin DataSetANTIGO.Active := False; DataSetANTIGO.SQLs.SelectSQL.Clear; DataSetANTIGO.SQLs.SelectSQL.Add(´SELECT FIRST 1 * FROM ´+TabelasBDANTIGO_Temp.Strings[I]); DataSetANTIGO.Active := True; TransactionANTIGO.StartTransaction; DataSetANTIGO.GetFieldNames(CamposBDANTIGO_Temp); // Armazenando o nome dos campos na variavel. DataSetNOVO.Active := False; DataSetNOVO.SQLs.SelectSQL.Clear; DataSetNOVO.SQLs.SelectSQL.Add(´SELECT FIRST 1 * FROM ´+TabelasBDNOVO_Temp.Strings[I]); DataSetNOVO.Active := True; TransactionNOVO.StartTransaction; DataSetNOVO.GetFieldNames(CamposBDNOVO_Temp); for J := 0 to CamposBDANTIGO_Temp.Count - 1 do begin WriteLn(ArquivoTexto, TabelasBDANTIGO_Temp.Strings[I]+´;´+CamposBDANTIGO_Temp[J]+´;´+RetornaTipo(DataSetANTIGO.Fields[J].DataType)+´;´+CamposBDNOVO_Temp[J]+RetornaTipo(DataSetNOVO.Fields[J].DataType)); end; end; Closefile(ArquivoTexto); end; procedure TFPrincipal.ConectarBD(); //Procedure de conexao aos bancos de dados. var CaminhoBDNOVO :String; begin CaminhoBDNOVO := ´E:\BD\CONSULTORIO_FACIL.NOT´; DataBaseANTIGO.DBName := ´localhost:´+CaminhoBDANTIGO; DataBaseANTIGO.ConnectParams.UserName := ´SYSDBA´; DataBaseANTIGO.ConnectParams.Password := ´masterkey´; DataBaseANTIGO.SQLDialect := 3; DataBaseANTIGO.Connected := TRUE; //TransactionANTIGO.Active:=True; if DataBaseANTIGO.Connected then Begin showmessage(´antigo conectado´); Richlog.Lines.Add(´Conectado ao banco de dados antigo com sucesso.´); Richlog.Lines.Add(´Agora tentando conectar com o novo Banco de Dados...´); DataBaseNOVO.DBName := ´localhost:´+CaminhoBDNOVO; DataBaseNOVO.ConnectParams.UserName := ´SYSDBA´; DataBaseNOVO.ConnectParams.Password := ´masterkey´; DataBaseNOVO.SQLDialect := 3; DataBaseNOVO.Connected := TRUE; //TransactionNOVO.Active:=True; DicionarioDeDados(); end; end; procedure TFPrincipal.FormClose(Sender: TObject; var Action: TCloseAction); begin Application.Terminate(); end; procedure TFPrincipal.FormShow(Sender: TObject); begin TransactionANTIGO.Active := false; TransactionNOVO.Active := false; LerIni(CaminhoBDANTIGO); end;
Bem, esse e o codigo completo.
Qualquer sugestao sobre o codigo, sera mto bem vinda!
Grato!
Icarus
Curtir tópico
+ 0Posts
07/11/2007
Jeimyson
Tento de ajudar... mas pode guardar o abraço.
TransactionANTIGO.StartTransaction;
Tira isso do laço, ele ta tentando startar a transação que vc já startou.
Flwww´s
8)
Gostei + 0
07/11/2007
Icarus
Cara, nao adiantou. Mesmo eu tirando ele da o mesmo erro:´Transaction is active.
E agora? :(
Gostei + 0
07/11/2007
Gandalf.nho
Gostei + 0
07/11/2007
Icarus
Eu ja tentei fazer isso tambem, modifiquei o Active do DataSetANTIGO.Transaction pra false e pra true, mas nao adiantou nada...
Mais alguma ideia, meus caros? =/
Gostei + 0
07/11/2007
Gandalf.nho
Gostei + 0
07/11/2007
Icarus
Project Pmigracao.exe raised exception class EFIBClientError with message:´Transaction is active.´
Help, I need somebody, help! :(
Gostei + 0
07/11/2007
Icarus
unit UPrincipal;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, FIBDatabase, pFIBDatabase, DB, FIBDataSet, pFIBDataSet, Gauges,
ExtCtrls, StdCtrls, IniFiles, ComCtrls, FIBQuery, pFIBQuery;
type
TFPrincipal = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Shape0: TShape;
Shape1: TShape;
Shape2: TShape;
Shape3: TShape;
Shape4: TShape;
Shape5: TShape;
RichLog: TRichEdit;
DataBaseANTIGO: TpFIBDatabase;
DataSetANTIGO: TpFIBDataSet;
TransactionANTIGO: TpFIBTransaction;
DataBaseNOVO: TpFIBDatabase;
DataSetNOVO: TpFIBDataSet;
TransactionNOVO: TpFIBTransaction;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure LerIni(var CaminhoBDANTIGO: string);
procedure ConectarBD();
procedure DicionarioDeDados();
end;
var
FPrincipal : TFPrincipal;
CaminhoBDANTIGO : String; //Declarando a variavel globaldo caminho do BD a ser migrado, a ser usada na procedure LeIni.
CaminhoArquivoIni : TIniFile; //Criando a variavel da localizacao do arquivo .INI
implementation
{$R *.dfm}
uses UOpenBox;
////////// Procedures ////////////
function RetornaTipo(Campo:TFieldType):string;
begin
case campo of
ftUnknown: result:=´Desconhecido´ ;
ftString: result := ´Varchar´;
ftSmallint: result := ´Integer´;
ftInteger: result := ´Integer´ ;
ftWord: result := ´Integer´;
ftBoolean: result := ´Char(1)´;
ftFloat: result :=´DOUBLE PRECISION´;
ftCurrency: result :=´DOUBLE PRECISION´;
ftBCD: result :=´DOUBLE PRECISION´;
ftDate: result :=´Timestamp´;
ftTime: result :=´TimeStamp´;
ftDateTime: result :=´TimeStamp´;
ftBytes: result :=´integer´ ;
ftVarBytes: result :=´integer´;
ftAutoInc: result :=´Integer´;
ftBlob: result :=´Blob´;
ftMemo: result :=´Blob´;
ftGraphic: result :=´Blob´;
ftFmtMemo: result :=´Blob´;
ftParadoxOle: result :=´Blob´;
ftDBaseOle: result :=´Blob´;
ftTypedBinary: result :=´Integer´;
ftCursor: result :=´Integer´;
ftFixedChar: result :=´Char´;
ftWideString: result :=´Varchar´;
ftLargeint: result :=´integer´;
ftADT: result :=´blob´;
ftArray: result :=´blob´;
ftReference: result :=´blob´;
ftDataSet: result :=´blob´;
ftOraBlob: result :=´Blob´;
ftOraClob: result :=´Blob´;
ftVariant: result :=´blob´;
ftInterface: result :=´blob´;
ftIDispatch: result :=´´;
ftGuid: result :=´´;
ftTimeStamp: result :=´TimeStamp´;
ftFMTBcd: result :=´blob´;
ftFixedWideChar: result :=´Char´;
ftWideMemo: result :=´Blob´;
ftOraTimeStamp: result :=´TimeStamp´;
ftOraInterval: result :=´integer´;
end;
end;
procedure TFPrincipal.LerIni(var CaminhoBDANTIGO: string);
// Procedure para ler o arquivo INI.
// Variaveis globais usadas sao:
// CaminhoBDANTIGO : String;
// CaminhoArquivoIni : TIniFile;
begin
CaminhoArquivoIni := TIniFile.Create(´C:\Arquivos de Programas\Notoriun\Laudo Facil\consultorio.ini´); //Atribuindo o caminho a variavel.
CaminhoBDANTIGO := CaminhoArquivoIni.ReadString(´BancoDados´, ´local_Text´, CaminhoBDANTIGO); //Assimilando o valor a Variavel CaminhoDBANTIGO.
CaminhoArquivoIni.Free; //Liberando...
if (CaminhoBDANTIGO = ´´) then //Caso nao ache o Local_text...
begin
RichLog.Lines.Add(´Banco de dados nao encontrado no diretorio padrao.´);
Application.CreateForm(TFOpenBox, FOpenBox);
FopenBox.Show();
end else
Shape0.Brush.Color := clgreen;
RichLog.Lines.Add(´locahost:´+CaminhoBDANTIGO); //Coloca o valor no Label.
ConectarBD();
end;
procedure TFPrincipal.DicionarioDeDados();
// Esta procedure tem como objetivo criar um arquivo de texto em aonde o migrador esta sendo executado e, em seguida,
// escrever o nome dos campos da tabela antiga e o nome da tabela, tal como tipo do campo, etc.
var
ArquivoTexto : TextFile; //Declarando var do arquivo de texto.
CamposBDANTIGO_Temp : TStringList; //Declarando a variavel que armazenara o nome dos campos, temporariamente.
TabelasBDANTIGO_Temp : TStringList; //Declarando a variavel que armazenara o nome dos campos, temporariamente.
CamposBDNOVO_Temp : TStringList; //Declarando a variavel que vai armazenar o nome dos campos do Banco novo.
TabelasBDNOVO_Temp : TStringList; //Declarando a variavel que armazenara o nome das tabelas.
I,J,K: Integer; //Declarando o contador.
begin
CamposBDANTIGO_Temp := TStringList.Create;
TabelasBDANTIGO_Temp := TStringList.Create;
CamposBDNOVO_Temp := TStringList.Create;
TabelasBDNOVO_Temp := TStringList.Create;
// DataSetANTIGO.Transaction.Active := True;
AssignFile(ArquivoTexto, ´C:\BD.txt´);
Richlog.Lines.Add(´Arquivo do dicionario de dados criado.´);
Rewrite(ArquivoTexto);
DataBaseANTIGO.GetTableNames(TabelasBDANTIGO_Temp, FALSE); // Armazenando o nome das tabelas na variavel.
DataBaseNOVO.GetTableNames(TabelasBDNOVO_Temp, FALSE); // Armazenando o nome das tabelas na variavel.
for I := 0 to TabelasBDANTIGO_Temp.Count - 1 do
Begin
DataSetANTIGO.Active := False;
DataSetANTIGO.SQLs.SelectSQL.Clear;
DataSetANTIGO.SQLs.SelectSQL.Add(´SELECT FIRST 1 * FROM ´+TabelasBDANTIGO_Temp.Strings[I]);
DataSetANTIGO.Active := True;
TransactionANTIGO.StartTransaction;
DataSetANTIGO.GetFieldNames(CamposBDANTIGO_Temp); // Armazenando o nome dos campos na variavel.
DataSetNOVO.Active := False;
DataSetNOVO.SQLs.SelectSQL.Clear;
DataSetNOVO.SQLs.SelectSQL.Add(´SELECT FIRST 1 * FROM ´+TabelasBDNOVO_Temp.Strings[I]);
DataSetNOVO.Active := True;
TransactionNOVO.StartTransaction;
DataSetNOVO.GetFieldNames(CamposBDNOVO_Temp);
for J := 0 to CamposBDANTIGO_Temp.Count - 1 do
begin
WriteLn(ArquivoTexto, TabelasBDANTIGO_Temp.Strings[I]+´;´+CamposBDANTIGO_Temp[J]+´;´+RetornaTipo(DataSetANTIGO.Fields[J].DataType)+´;´+CamposBDNOVO_Temp[J]+RetornaTipo(DataSetNOVO.Fields[J].DataType));
end;
end;
Closefile(ArquivoTexto);
end;
procedure TFPrincipal.ConectarBD();
//Procedure de conexao aos bancos de dados.
var
CaminhoBDNOVO :String;
begin
CaminhoBDNOVO := ´E:\BD\CONSULTORIO_FACIL.NOT´;
DataBaseANTIGO.DBName := ´localhost:´+CaminhoBDANTIGO;
DataBaseANTIGO.ConnectParams.UserName := ´SYSDBA´;
DataBaseANTIGO.ConnectParams.Password := ´masterkey´;
DataBaseANTIGO.SQLDialect := 3;
DataBaseANTIGO.Connected := TRUE;
TransactionANTIGO.Active := True;
if DataBaseANTIGO.Connected then
Begin
showmessage(´antigo conectado´);
Richlog.Lines.Add(´Conectado ao banco de dados antigo com sucesso.´);
Richlog.Lines.Add(´Agora tentando conectar com o novo Banco de Dados...´);
DataBaseNOVO.DBName := ´localhost:´+CaminhoBDNOVO;
DataBaseNOVO.ConnectParams.UserName := ´SYSDBA´;
DataBaseNOVO.ConnectParams.Password := ´masterkey´;
DataBaseNOVO.SQLDialect := 3;
DataBaseNOVO.Connected := TRUE;
TransactionNOVO.Active := True;
DicionarioDeDados();
end;
end;
procedure TFPrincipal.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Application.Terminate();
end;
procedure TFPrincipal.FormShow(Sender: TObject);
begin
LerIni(CaminhoBDANTIGO);
end;
end.
Fiz assim.
Mas continua a mesma coisa sobre o transaction =/...
Gostei + 0
08/11/2007
Icarus
Gostei + 0
09/11/2007
Icarus
Bem, quando os bancos de dados sao diferentes, eles dao problema (´Transaction is active´), mas quando sao iguais, nao.
O que sera?
Grato.
Gostei + 0
09/11/2007
Martins
Condicionais com IF ... Then
Bons códigos!
Gostei + 0
09/11/2007
Gandalf.nho
Ex:
DataSetANTIGO.Active := True; TransactionANTIGO.StartTransaction;
Faça assim (testando primeiro):
if not TransactionANTIGO.InTransaction then TransactionANTIGO.StartTransaction; DataSetANTIGO.Active := True;
Repita isso para todos os casos similares.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)