Na programação com componentes DBExpress, o componente TSQLConnection tem dois métodos muito interessantes:
- TSQLConnection.Execute – para comandos SQL que incluem parâmetros ou esperam o retorno de cursores.
- TSQLConnection.ExecuteDirect – para comandos SQL sem parâmetros.
A utilização destes métodos elimina a necessidade de utilizar SQL DataSet para tarefas diretas. Ambos métodos retornam o número de registros afetados pelas instrução SQL, diferente do que está escrito na ajuda do Delphi 2007.
No método ExecuteSQLDirect a seguir, temos algumas técnicas interessantes:
- Overload do método, podendo utiliza-lo de forma simples e a assinatura completa para a necessidade de tratar todos os parâmetros.
- Assert, para verificar se os parâmetros passados estão como esperado. Esta é uma técnica importante para identificar erros durante o desenvolvimento e que pode ser eliminado da versão final com uma diretiva de compilação.
- Controle de Transações com o DBX4, no Delphi 2007 o controle de transações foi reimplementado e os métodos existentes nas versões anteriores marcados como deprecated.
- Manter códigos ligados a conexão e transação em um único lugar.
function ExecuteSQLDirect(SQLConnection: TSQLConnection;
const SQL: string; var AffectedRows: Integer): boolean; overload;
var
Transaction: TDBXTransaction;
begin
Assert(SQLConnection <> nil, 'SQLConnection can''t be nil');
Assert(SQL <> EmptyStr, 'SQL can''t be empty');
Transaction:= SQLConnection.BeginTransaction;
try
try
AffectedRows:= SQLConnection.ExecuteDirect(SQL);
except
AffectedRows:= 0;
end;
finally
Result:= AffectedRows > 0;
if Result then
SQLConnection.CommitFreeAndNil(Transaction)
else
SQLConnection.RollbackFreeAndNil(Transaction);
end;
end;
function ExecuteSQLDirect(const SQL: string): boolean; overload;
var
Rows: Integer;
begin
Result:= ExecuteSQLDirect(MainDataModule.SQLConnection,
SQL, Rows);
end;
Implementei este código no mesmo Data Module onde mantenho o componente de conexão TSQLConnection, permitindo que eu tenha uma versão mais simples de ExecuteSQLDirect, passando o TSQLConnection.
O código a seguir foi implementado em outro Data Module, note o método DeleteAllColumns, este é o método que será chamado a partir das ações dos formulários, separando o código de tratamento dos dados. E se algum erro acontecer durante a exclusão dos registros, uma exceção de tipo específico a este domínio será levantada, ajudando na identificação dos possível erros em tempo de execução.
procedure TDataModuleImport.DeleteAllColumns;
const
SQL = 'DELETE FROM FPL_IMP_COLUMN WHERE FILE_ID = %d';
EMsg = 'Não foi possível excluir todas as colunas.';
begin
if CDSImpFileID.IsNull then
Exit;
if not ExecuteSQLDirect(Format(SQL, [CDSImpFileID.Value])) then
raise EColumnError.Create(EMsg);
end;
Note que a mensagem de erro neste método está em português e no outro método, quando utilizei o Assert, as mensagens estão em inglês. Isto é, por que as mensagens de Assert são para o programador e não para o usuário final.