Problema FQuery - Acess Violation

25/11/2020

0

Boa tarde! Estou tendo problemas na criação do meu FQuery, gera um acess violation no momento da execução sinalizando a linha FQuery.Connection := DM.Conn;

unit uBaseDAO;

interface

uses uDM, System.SysUtils, FireDAC.Comp.Client;

type
  TBaseDAO = class

  protected
    FQuery: TFDQuery;
    constructor Create;
    destructor Destroy; override;

    function ExecutarComando(pSQL: string): integer;
    function RetornarDataSet(pSQL: string): TFDQuery;
    function HaRegistro(pSQL: string): integer;
  end;

implementation

{ TBaseDAO }

constructor TBaseDAO.Create;
begin
  inherited Create;
  FQuery := TFDQuery.Create(Nil);
  FQuery.Connection := DM.Conn;
end;

destructor TBaseDAO.Destroy;
begin

  Try
    if Assigned(FQuery) then
    begin
      FreeAndNil(FQuery);
    end;
  except
    on e: exception do
      raise exception.Create(e.Message);
  End;
end;


Tenho uma unit DataModule para armazenar a conexão
unit uDM;

interface

uses
  System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option,
  FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
  FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.PG,
  FireDAC.Phys.PGDef, FireDAC.VCLUI.Wait, Data.DB, FireDAC.Comp.Client,
  FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt,
  FireDAC.Comp.DataSet;

type
  TDM = class(TDataModule)
    Conn: TFDConnection;

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  DM: TDM;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

End.
Guilherme Algeri

Guilherme Algeri

Responder

Post mais votado

26/11/2020

provavelmente o problema ocorra porque o datamodule ainda não está criado.
recomendo fortemente você abstrair a conexão dentro da tua classe; não faça referências a objetos externos.

faça assim:
unit uBaseDAO;
 
interface
 
uses uDM, System.SysUtils, FireDAC.Comp.Client;
 
type
  TBaseDAO = class

  private
    FFDConnection: TFDConnection;

    procedure SetConnection(const Value: TFDConnection);
  protected
    FQuery: TFDQuery;
    constructor Create;
    destructor Destroy; override;
 
    function ExecutarComando(pSQL: string): integer;
    function RetornarDataSet(pSQL: string): TFDQuery;
    function HaRegistro(pSQL: string): integer;
  published
    property Connection: TFDConnection read FFDConnection write SetConnection;
  end;
 
implementation
 
{ TBaseDAO }
 
constructor TBaseDAO.Create;
begin
  inherited Create;
  FQuery := TFDQuery.Create(Nil);
end;
 
destructor TBaseDAO.Destroy;
begin
  Try
    if Assigned(FQuery) then
    begin
      FreeAndNil(FQuery);
    end;
  except
    on e: exception do
      raise exception.Create(e.Message);
  End;
  inherited Destroy;
end;

procedure TBaseDAO.SetConnection(const Value: TFDConnection);
begin
  FQuery.Connection := Value;
end;
obviamente, antes de executar os comandos, será necessário indicar a conexão:
BaseDAO := TBaseDAO.Create;
BaseDAO.Connection := DM.Conn; // indica a conexão que será utilizada

ou assim:
unit uBaseDAO;

interface
 
uses uDM, System.SysUtils, FireDAC.Comp.Client;
 
type
  TBaseDAO = class

  protected
    FQuery: TFDQuery;
    constructor Create(Connection: TFDConnection);
    destructor Destroy; override;
 
    function ExecutarComando(pSQL: string): integer;
    function RetornarDataSet(pSQL: string): TFDQuery;
    function HaRegistro(pSQL: string): integer;
  end;
 
implementation
 
{ TBaseDAO }
 
constructor TBaseDAO.Create(Connection: TFDConnection);
begin
  inherited Create;
  FQuery := TFDQuery.Create(Nil);
  FQuery.Connection := Connection;
end;
 
destructor TBaseDAO.Destroy;
begin
  Try
    if Assigned(FQuery) then
    begin
      FreeAndNil(FQuery);
    end;
  except
    on e: exception do
      raise exception.Create(e.Message);
  End;
  inherited Destroy;
end;
BaseDAO := TBaseDAO.Create( DM.Conn ); // indica a conexão ao instanciar a classe

Emerson Nascimento

Emerson Nascimento
Responder

Mais Posts

26/11/2020

Emerson Nascimento

provavelmente o problema ocorra porque o datamodule ainda não está criado.
recomendo fortemente você abstrair a conexão dentro da tua classe; não faça referências a objetos externos.

faça assim:
unit uBaseDAO;
 
interface
 
uses System.SysUtils, FireDAC.Comp.Client;
 
type
  TBaseDAO = class

  private
    FFDConnection: TFDConnection;

    procedure SetConnection(const Value: TFDConnection);
  protected
    FQuery: TFDQuery;
    constructor Create;
    destructor Destroy; override;
 
    function ExecutarComando(pSQL: string): integer;
    function RetornarDataSet(pSQL: string): TFDQuery;
    function HaRegistro(pSQL: string): integer;
  published
    property Connection: TFDConnection read FFDConnection write SetConnection;
  end;
 
implementation
 
{ TBaseDAO }
 
constructor TBaseDAO.Create;
begin
  inherited Create;
  FQuery := TFDQuery.Create(Nil);
end;
 
destructor TBaseDAO.Destroy;
begin
  Try
    if Assigned(FQuery) then
    begin
      FreeAndNil(FQuery);
    end;
  except
    on e: exception do
      raise exception.Create(e.Message);
  End;
  inherited Destroy;
end;

procedure TBaseDAO.SetConnection(const Value: TFDConnection);
begin
  FQuery.Connection := Value;
end;
obviamente, antes de executar os comandos, será necessário indicar a conexão:
BaseDAO := TBaseDAO.Create;
BaseDAO.Connection := DM.Conn; // indica a conexão que será utilizada

ou assim:
unit uBaseDAO;

interface
 
uses System.SysUtils, FireDAC.Comp.Client;
 
type
  TBaseDAO = class

  protected
    FQuery: TFDQuery;
    constructor Create(Connection: TFDConnection);
    destructor Destroy; override;
 
    function ExecutarComando(pSQL: string): integer;
    function RetornarDataSet(pSQL: string): TFDQuery;
    function HaRegistro(pSQL: string): integer;
  end;
 
implementation
 
{ TBaseDAO }
 
constructor TBaseDAO.Create(Connection: TFDConnection);
begin
  inherited Create;
  FQuery := TFDQuery.Create(Nil);
  FQuery.Connection := Connection;
end;
 
destructor TBaseDAO.Destroy;
begin
  Try
    if Assigned(FQuery) then
    begin
      FreeAndNil(FQuery);
    end;
  except
    on e: exception do
      raise exception.Create(e.Message);
  End;
  inherited Destroy;
end;
BaseDAO := TBaseDAO.Create( DM.Conn ); // indica a conexão ao instanciar a classe
Responder

26/11/2020

Guilherme Algeri

Boa tarde!
Depois de horas e horas debugando o código através de breakpoints acabei descobrindo que o Acess Violation estava acontece devido a falta de um "Inherited" no método destroy em uma das minhas Unit que consome a conexão com o banco. Na hora de executar ele estava entrando no método destroy antes mesmo de criar o objeto FDQuery, gerando assim o erro.
Obrigado pela ajuda pessoal
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar