Fórum Ajuda em criar uma camada de persistencia? #400408
05/05/2011
0
Mais estou com problema em montar os PARAMBYNAME no SQL (destaque em azul e em vermelho no CODE abaixo.
//iTypeCommand - 1 Insert, 2 Update, 3 - Delete - 4 select
function TDataModule2.ExecuteSQL(Query: TIBQuery; TableName: String; iTypeCommand: Integer): Boolean ;
var
i, iPos: integer;
sSQL, sInsert, sValues, sCreateFields, sVariavel: String;
sCreateParams: TStringList;
sCreateParamByName: String;
begin
sCreateParams := TStringList.Create;
try
try
//Verifica se a conexão esta OK
if not IBDatabase1.Connected then
IBDatabase1.Connected := True;
//Faz um select da tabela para saber quis são os campos
Query.SQL.Text := 'SELECT * FROM '+TableName;
Query.Open;
//Conta a quantidade de campos da tabela selecionada
for i := 0 to Pred(Query.Fields.Count) do
begin
//Se o iTypeCommand for = 1 então monta o insert
if iTypeCommand = 1 then
begin
if i < Pred(Query.Fields.Count) then
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName + ',';
sValues := sValues + ':' + Query.Fields[i].FieldName + ',';
sInsert := sInsert + Query.Fields[i].FieldName + ',';
end
else
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName;
sInsert := sInsert + Query.Fields[i].FieldName;
sValues := sValues + ':' + Query.Fields[i].FieldName;
end;
end
else
// Se o iTypeCommand for = 2 então monta o Update
if iTypeCommand = 2 then
begin
if i < Pred(Query.Fields.Count) then
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName + ',';
sValues := sValues + ':' + Query.Fields[i].FieldName + ',';
sInsert := sInsert + Query.Fields[i].FieldName + ',';
end
else
begin
//Recorto a primeira posição do campo antes da virgula
iPos := Pos(',', sCreateFields);
if iPos > 0 then
Delete(sCreateFields, 1, iPos);
//
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName;
sInsert := sInsert + Query.Fields[i].FieldName;
sValues := sValues + ':' + Query.Fields[i].FieldName;
end;
end
else
// Se o iTypeCommand for = 4 então monta o SELECT
if iTypeCommand = 4 then
begin
if i < Pred(Query.Fields.Count) then
begin
sInsert := sInsert + Query.Fields[i].FieldName + ',';
end
else
begin
sInsert := sInsert + Query.Fields[i].FieldName;
end;
end;
end;
//passa a instrução SQL para o comando cfe o iTypeCommand (1-Insert, 2-Update, 3-Delete - 4 select)
case iTypeCommand of
//Insert
1: sSQL := 'INSERT INTO '+ TableName +' (' + sInsert + ' ) VALUES ( '+ sValues + ' )';
//Update
2: sSQL := 'UPDATE '+ TableName +' SET '+ sCreateFields +' WHERE '+ Query.Fields[0].FieldName + ' = :OLD_' + Query.Fields[0].FieldName;
//Delete
3: sSQL := 'DELETE FROM ' + TableName + ' WHERE ' + Query.Fields[0].FieldName + ' = :OLD_' + Query.Fields[0].FieldName;
//Select
4: sSQL := 'SELECT '+ sInsert + ' FROM '+ TableName + ' WHERE ' + Query.Fields[0].FieldName + ' = ' + Query.Fields[0].FieldName;
end;
//Agora monta os parametros
case iTypeCommand of
//Insert
1:
begin
for i := 0 to Pred(Query.Fields.Count) do
begin
//Se o iTypeCommand for = 1 então monta o insert
if iTypeCommand = 1 then
begin
sCreateParamByName := sCreateParamByName + 'ParamByName(":' + Query.Fields[i].FieldName + '").Value' +
' = ' + 'Teste Variavel' +';'+#10#13; //sVariavel;
end;
end;
end;
{ //Update
2:
//Delete
3:
//Select
4: }
end;
with Query do
begin
Close;
SQL.Clear;
SQL.Add(sSQL);
sCreateParamByName;
excSQL; // ou Open
end;
Result := True;
except
Result := False;
end;
finally
sCreateParams.Free;
end;
end;Obrigado pessoal.
Adriano Dolce
Curtir tópico
+ 0Posts
05/05/2011
Adriano Dolce
for i := 0 to Pred(Query.Fields.Count) do
begin
//Se o iTypeCommand for = 1 então monta o insert
if iTypeCommand = 1 then
begin
sCreateParamByName := sCreateParamByName + 'ParamByName("' + Query.Fields[i].FieldName + '").Value' +
' = ' + 'Teste Variavel' +';'+#10#13; //sVariavel;
end;Então este é o resultado deste bloco ai
ParamByName("EMP_NO").Value = Teste Variavel;'#$A#$D'ParamByName("FIRST_NAME").Value = Teste Variavel;'#$A#$D'ParamByName("LAST_NAME").Value = Teste Variavel;'#$A#$D'ParamByName("PHONE_EXT").Value = Teste Variavel;'#$A#$D'ParamByName("HIRE_DATE").Value = Teste Variavel;'#$A#$D'ParamByName("DEPT_NO").Value = Teste Variavel;'#$A#$D'ParamByName("JOB_CODE").Value = Teste Variavel;'#$A#$D'ParamByName("JOB_GRADE").Value = Teste Variavel;'#$A#$D'ParamByName("JOB_COUNTRY").Value = Teste Variavel;'#$A#$D'ParamByName("SALARY").Value = Teste Variavel;#$A#$D
Gostei + 0
06/05/2011
Adriano Dolce
TTipoComando = (tcInsert, tcUpdate, tcDelete, tcSelect);
function TDataModule2.ExecuteSQL(Query: TIBQuery; TableName: String;
iTypeCommand: TTipoComando): Boolean;
var
i, iPos: integer;
sSQL, sInsert, sValues, sCreateFields, sVariavel: String;
sCreateParams: TStringList;
sCreateParamByName: String;
begin
sCreateParams := TStringList.Create;
try
try
//Verifica se a conexão esta OK
if not IBDatabase1.Connected then
IBDatabase1.Connected := True;
//Faz um select da tabela para saber quis são os campos
Query.SQL.Text := 'SELECT * FROM '+TableName;
Query.Open;
//Conta a quantidade de campos da tabela selecionada
for i := 0 to Pred(Query.Fields.Count) do
begin
case iTypeCommand of
tcInsert:
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName + ',';
sInsert := sInsert + Query.Fields[i].FieldName + ',';
sValues := sValues + ':' + Query.Fields[i].FieldName + ',';
end;
tcUpdate:
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName + ',';
end;
tcSelect:
begin
sCreateFields := Query.Fields[i].FieldName + ',';
sInsert := sInsert + Query.Fields[i].FieldName + ',';
end;
end;
end;
//Final do Loop
case iTypeCommand of
tcInsert:
begin
//recorto a ultima virgula da montagem do SQL
Delete(sInsert, Length(sInsert), 1);
Delete(sValues, Length(sValues), 1);
end;
tcUpdate:
begin
//Recorto a primeira posição do campo antes da virgula
//pois a PK não é modificado no Update
iPos := Pos(',', sCreateFields);
if iPos > 0 then
Delete(sCreateFields, 1, iPos);
//recorto também a ultima virgula da montagem do SQL
Delete(sCreateFields, Length(sCreateFields), 1);
end;
//recorto a ultima virgula da montagem do SQL
tcSelect: Delete(sInsert, Length(sInsert), 1);
end;
//passa a instrução SQL para o comando cfe o iTypeCommand (1-Insert, 2-Update, 3-Delete - 4 select)
case iTypeCommand of
tcInsert: sSQL := 'INSERT INTO '+ TableName +' (' + sInsert + ' ) VALUES ( '+ sValues + ' )';
tcUpdate: sSQL := 'UPDATE '+ TableName +' SET '+ sCreateFields +' WHERE '+ Query.Fields[0].FieldName + ' = :OLD_' + Query.Fields[0].FieldName;
tcDelete: sSQL := 'DELETE FROM ' + TableName + ' WHERE ' + Query.Fields[0].FieldName + ' = :OLD_' + Query.Fields[0].FieldName;
tcSelect: sSQL := 'SELECT '+ sInsert + ' FROM '+ TableName + ' WHERE ' + Query.Fields[0].FieldName + ' = ' + Query.Fields[0].FieldName;
end;
//Agora monta o SQL na query
case iTypeCommand of
tcInsert, tcUpdate:
begin
for i := 0 to Pred(Query.Fields.Count) do
begin
sCreateParamByName := sCreateParamByName + 'ParamByName("' + Query.Fields[i].FieldName + '").Value' +
' = ' + 'Teste Variavel' +';'+#10#13; //sVariavel;
end;
end;
{tcDelete:
tcSelect: }
end;
//Monta o SQL
with Query do
begin
Close;
SQL.Clear;
SQL.Add(sSQL);
//sCreateParamByName;
ExecSQL; // ou Open
end;
Result := True;
except
Result := False;
end;
finally
sCreateParams.Free;
end;
end;Mais a duvida de como fazer algo que dê para passar parametros para montar o SQL continua, estou vendo que é algo meio que impossivel de ser feito desta forma, mais então como seria a forma que o pessoal monta esta tal de PERSISTENCIA?
Gostei + 0
07/05/2011
Adriano Dolce
Na camada de persistencia mudei a função, agora retorna um string
function TDataModule2.ExecuteSQL(Query: TIBQuery; TableName: String;
iTypeCommand: TTipoComando; xEmployee: TEmployee): String;
var
i, iPos: integer;
sInsert, sValues, sCreateFields, sVariavel: String;
sCreateParams: TStringList;
sCreateParamByName: String;
begin
sCreateParams := TStringList.Create;
try
try
//Verifica se a conexão esta OK
if not IBDatabase1.Connected then
IBDatabase1.Connected := True;
//Faz um select da tabela para saber quis são os campos
Query.SQL.Text := 'SELECT * FROM '+TableName;
Query.Open;
//Conta a quantidade de campos da tabela selecionada
for i := 0 to Pred(Query.Fields.Count) do
begin
case iTypeCommand of
tcInsert:
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName + ',';
sInsert := sInsert + Query.Fields[i].FieldName + ',';
sValues := sValues + ':' + Query.Fields[i].FieldName + ',';
end;
tcUpdate:
begin
sCreateFields := sCreateFields + Query.Fields[i].FieldName + ' = :' + Query.Fields[i].FieldName + ',';
end;
tcSelect:
begin
sCreateFields := Query.Fields[i].FieldName + ',';
sInsert := sInsert + Query.Fields[i].FieldName + ',';
end;
end;
end;
//Final do Loop
case iTypeCommand of
tcInsert:
begin
//recorto a ultima virgula da montagem do SQL
Delete(sInsert, Length(sInsert), 1);
Delete(sValues, Length(sValues), 1);
end;
tcUpdate:
begin
//Recorto a primeira posição do campo antes da virgula
//pois a PK não é modificado no Update
iPos := Pos(',', sCreateFields);
if iPos > 0 then
Delete(sCreateFields, 1, iPos);
//recorto também a ultima virgula da montagem do SQL
Delete(sCreateFields, Length(sCreateFields), 1);
end;
//recorto a ultima virgula da montagem do SQL
tcSelect: Delete(sInsert, Length(sInsert), 1);
end;
//passa a instrução SQL para o comando cfe o iTypeCommand
case iTypeCommand of
tcInsert: Result := 'INSERT INTO '+ TableName +' (' + sInsert + ' ) VALUES ( '+ sValues + ' )';
tcUpdate: Result := 'UPDATE '+ TableName +' SET '+ sCreateFields +' WHERE '+ Query.Fields[0].FieldName + ' = :' + Query.Fields[0].FieldName;
tcDelete: Result := 'DELETE FROM ' + TableName + ' WHERE ' + Query.Fields[0].FieldName + ' = :' + Query.Fields[0].FieldName;
tcSelect: Result := 'SELECT '+ sInsert + ' FROM '+ TableName + ' WHERE ' + Query.Fields[0].FieldName + ' = ' + Query.Fields[0].FieldName;
end;
except
on E:Exception do
begin
raise Exception.Create('Erro! '+ E.Message);
Result := EmptyStr;
end;
end;
finally
sCreateParams.Free;
end;
end;Na camada ne negocio criei 4 funções que chamam a função da persistencia e criei uma função ja com os selects e parametros.
As funções que chamam a função da persistencia ficou assim
function TEmployee.ExecuteInsertSQL: String; begin Result := DataModule2.ExecuteSQL(DataModule2.qry_Temp,'XEMPLOYEE',tcInsert,Self) end; function TEmployee.ExecuteUpdateSQL: String; begin Result := DataModule2.ExecuteSQL(DataModule2.qry_Temp,'XEMPLOYEE',tcUpdate,Self) end; function TEmployee.ExecuteDeleteSQL: String; begin Result := DataModule2.ExecuteSQL(DataModule2.qry_Temp,'XEMPLOYEE',tcDelete,Self) end; function TEmployee.ExecuteSelectSQL: String; begin Result := DataModule2.ExecuteSQL(DataModule2.qry_Temp,'XEMPLOYEE',tcSelect,Self) end;
e a que passa os parametros ficou assim (tem TFields incompletos, esta apenas pra teste) Poderia passar direto sem utilizar a variavel sSQL, mais é pq gosto de utilizar variaveis.
procedure TEmployee.ExecuteParams(Query: TIBQuery; iTypeCommand: TFormaComando);
var
sSQL: String;
begin
try
case iTypeCommand of
fcInsert : sSQL := ExecuteInsertSQL;
fcUpdate : sSQL := ExecuteUpdateSQL;
fcDelete : sSQL := ExecuteDeleteSQL;
fcSelect : sSQL := ExecuteSelectSQL;
end;
//Passa os parametros
Query.Close;
Query.SQL.Clear;
Query.SQL.Add(sSQL);
Query.ParamByName('Emp_No').Value := FEmp_No;
//Para o comando delete não precisa passar os parametros
if not(iTypeCommand = fcDelete) then
begin
Query.ParamByName('First_Name').Value := FFirst_Name;
Query.ParamByName('Last_name').Value := FLast_name;
Query.ParamByName('Phone_Ext').Value := FPhone_Ext;
Query.ParamByName('Hire_date').Value := Date; //FHire_date;
Query.ParamByName('Dept_No').Value := 900;//xEmployee.Dept_No;
Query.ParamByName('Job_Code').Value := 'CFO'; //xEmployee.Job_Code;
Query.ParamByName('Job_Grade').Value := 3; //xEmployee.Job_Grade;
Query.ParamByName('Job_Country').Value := 'BRASIL'; //xEmployee.Job_Country;
Query.ParamByName('Salary').Value := FSalary;
end;
//Verifica que tipo de comando deve executar
case iTypeCommand of
fcInsert, fcUpdate, fcDelete: Query.ExecSQL;
fcSelect: Query.Open;
end;
if not DataModule2.IBTransaction1.Active then
DataModule2.IBTransaction1.Active := True;
DataModule2.IBTransaction1.Commit;
except
on E:Exception do
begin
raise Exception.Create('Erro! '+ E.Message);
DataModule2.IBTransaction1.Rollback;
end;
end;
end;
Na camada de interface chamo assim
procedure Tfrm_cadastro.btnInsertClick(Sender: TObject);
var
OK: Boolean;
begin
//No método Set eu escrevo as variaveis para o banco de dados
SetExecute;
try
//aqui executo o select com seus parametros que fica na classe de negocio
xEmployee.ExecuteParams(DataModule2.qry_Temp,fcInsert);
if OK then
begin
LimparCampos(True);
xEmployee.Limpar;
end;
except
raise Exception.Create('Erro! Não foi possível executar este processo.');
edt_Codigo.SetFocus;
end;
end;
procedure Tfrm_cadastro.btnUpdateClick(Sender: TObject);
var
OK: Boolean;
begin
//No método Set eu escrevo as variaveis para o banco de dados
SetExecute;
try
//aqui executo o select com seus parametros que fica na classe de negocio
xEmployee.ExecuteParams(DataModule2.qry_Temp,fcUpdate);
if OK then
begin
LimparCampos(True);
xEmployee.Limpar;
end;
except
on E:Exception do
begin
raise Exception.Create('Erro! '+ E.Message);
//raise Exception.Create('Erro! Não foi possível executar este processo.');
edt_Codigo.SetFocus;
end;
end;
end;
procedure Tfrm_cadastro.btnDeleteClick(Sender: TObject);
var
OK: Boolean;
begin
//No método Set eu escrevo as variaveis para o banco de dados
SetExecute;
try
//aqui executo o select com seus parametros que fica na classe de negocio
xEmployee.ExecuteParams(DataModule2.qry_Temp,fcDelete);
if OK then
begin
LimparCampos(True);
xEmployee.Limpar;
end;
except
raise Exception.Create('Erro! Não foi possível executar este processo.');
edt_Codigo.SetFocus;
end;
end;
procedure Tfrm_cadastro.btnSelectClick(Sender: TObject);
var
OK: Boolean;
begin
//No método Set eu escrevo as variaveis para o banco de dados
SetExecute;
try
//aqui executo o select com seus parametros que fica na classe de negocio
xEmployee.ExecuteParams(DataModule2.qry_Temp,fcSelect);
if OK then
begin
LimparCampos(True);
xEmployee.Limpar;
end;
except
raise Exception.Create('Erro! Não foi possível executar este processo.');
edt_Codigo.SetFocus;
end;
end;e criei nesta camada uma procedure para gravar os dados para o banco que resolvi chamar de SetExecute (Não sei bem se o nome correspone,pois até hj confundo muito os métodos get (ler) e set (escrever)) :D
procedure Tfrm_cadastro.SetExecute; begin (* aqui estou escrevendo (GRAVANDO) para o banco o valor das variaveis *) xEmployee.Emp_No := StrToInt(edt_Codigo.Text); xEmployee.First_Name := edt_nome.Text; xEmployee.Last_name := edt_sobrenome.Text; xEmployee.Phone_Ext := '41-8815-6366'; xEmployee.Hire_date := Date; xEmployee.Dept_No := 11; xEmployee.Job_Code := 'BRA'; xEmployee.Job_Grade := 155; xEmployee.Job_Country := 'STR TRY'; xEmployee.Salary := StrToCurr(edt_salario.Text); end;
Falta passar alguns edits ainda.
Bom desta forma ai, vai dar trabalho pq cada propriedades de interface que eu criar devo setar o parametros...
Foi isso que eu imaginei, que da pra fazer.
Gostei + 0
22/04/2013
José
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)