You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Access Violation与数据类型不匹配问题排查求助

问题描述

同一行代码先后触发两种错误:

  1. 最初抛出EOleException异常,提示“Data type mismatch in criteria expression”(条件表达式中数据类型不匹配);
  2. 修改SQL语句硬编码手机号后,又出现Access Violation错误,且错误会随注释代码行转移。

数据库相关字段均为String(ShortText)类型,此代码结构在其他窗体可正常运行,求排查思路。

排查思路

针对EOleException(数据类型不匹配)

  • 检查EventDetails.FrmDetails.Host_Phonenum变量:确认该值是否为空、包含特殊字符(如单引号),或被错误赋值为非字符串类型(比如整数)。即便数据库字段是字符串,传入变量类型不匹配也会触发该错误。
  • 替换动态拼接SQL为参数化查询:彻底避免字符串拼接带来的类型问题和注入风险,示例代码:
    adouser.SQL.Text := 'SELECT First_Name, Last_Name, Phone_Number, ProfilePic, BIO, Events_Hosted FROM tblUsers WHERE Phone_Number = :Phone';
    adouser.Parameters.ParamByName('Phone').Value := EventDetails.FrmDetails.Host_Phonenum;
    
  • 验证SQL有效性:将拼接后的SQL直接在Access数据库中执行,排查字段名、变量值是否正确。

针对Access Violation(访问违规)

  • 检查User变量初始化:getinfo中若查询结果为空(adouser.IsEmpty为True),User会保持nil状态,此时调用user.GetName等方法必然触发访问违规。需在assignvalues前判断User是否有效:
    procedure TFrmAccountDetails.FormShow(Sender: TObject);
    begin
      getinfo;
      if Assigned(User) then
        assignvalues
      else
        ShowMessage('未找到用户信息');
    end;
    
  • 修正TUser构造函数参数顺序:当前getinfo中调用Tuser.Create(FName, LName, ProfilePic, BIO, Host_Phone, Hosted_events),但TUser构造函数定义为Create(sFirstName, sLastName, sPhone, sProfilePic, sBio, sNum_Hosted),参数顺序完全不匹配!这会导致FPhone等成员变量被错误赋值,甚至内存混乱,是触发访问违规的核心原因。正确调用应为:
    User := Tuser.Create(FName, LName, Host_Phone, ProfilePic, BIO, Hosted_events);
    
  • 检查窗体变量生命周期:确认EventDetails.FrmDetails已正确创建,Host_Phonenum有效,避免访问已释放的窗体对象。
  • 校验图片路径:img_profile.Picture.LoadFromFile(user.getProfilepic)中,若ProfilePic字段为空或路径无效,可能触发异常进而引发内存访问问题,建议添加路径存在性判断。
相关代码

unit AccountDetails

unit AccountDetails;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Buttons, StdCtrls, ImgList, jpeg, pngimage, accdetails, DM;

type
  TFrmAccountDetails = class(TForm)
    Image1: TImage;
    Img_Profile: TImage;
    Lbl_BioHeading: TLabel;
    Lbl_Phone: TLabel;
    LblBio: TLabel;
    LblName: TLabel;
    Shape1: TShape;
    Panel1: TPanel;
    Image2: TImage;
    lbl_EventsHosted: TLabel;
    procedure Image2Click(Sender: TObject);
   //procedure FormShow(Sender: TObject);
    procedure getinfo;
    procedure assignvalues;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FrmAccountDetails: TFrmAccountDetails;
  User: Tuser;

implementation

uses EventDetails;
{$R *.dfm}

procedure TFrmAccountDetails.assignvalues;
begin
lblName.Caption:=user.GetName;  (*** Author Kyle most likely means this line. ***)
lbl_phone.Caption:='Phone Number: '+user.GetPhone;
LblBio.Caption:='';
lblbio.Caption:=user.getBio;
img_profile.Picture.LoadFromFile((user.getProfilepic));
lbl_eventshosted.Caption:='Events Hosted: '+user.getnum_hosted;
end;

procedure TFrmAccountDetails.FormShow(Sender: TObject);
begin
getinfo;
assignvalues;
end;

procedure TFrmAccountDetails.getinfo;
var
  FName, LName, ProfilePic, BIO, Host_Phone, Hosted_events: string;
begin
  User := nil;
  with DM.DataModule1 do
  begin
    adouser.Close;
    adouser.SQL.Clear;
    adouser.SQL.Text :=
      'SELECT First_Name, Last_Name, Phone_Number, ProfilePic, BIO, Events_Hosted ' +
      'FROM tblUsers WHERE Phone_Number = ' + QuotedStr(EventDetails.FrmDetails.Host_Phonenum);

    // Execute the query and retrieve all the rows into the dataset
    adouser.Open;
    begin
    adouser.First;
    if not adouser.IsEmpty then
    begin
      FName := adouser.FieldByName('First_Name').AsString;
      LName := adouser.FieldByName('Last_Name').AsString;
      ProfilePic := adouser.FieldByName('ProfilePic').AsString;
      BIO := adouser.FieldByName('BIO').AsString;
      Hosted_events := adouser.FieldByName('Events_Hosted').AsString;
      Host_Phone := adouser.FieldByName('Phone_Number').AsString;
     User := Tuser.Create(FName, LName, ProfilePic, BIO, Host_Phone, Hosted_events);
    end;
    end;
  end;
end;

procedure TFrmAccountDetails.Image2Click(Sender: TObject);
begin
  Close;
end;

end.

unit AccDetails

unit AccDetails;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, jpeg;


  type
  TUser = class
  private
    FProfilePic: string;
    FBio: string;
    FFirstName: string;
    FLastName: string;
    FPhone: string;
    FNum_Hosted: string;

  public
    constructor Create(sFirstName, sLastName, sPhone, sProfilePic, sBio, sNum_Hosted: string);
    function GetProfilePic: string;
    function GetBio: string;
    function GetName: string; // Updated function name
    function GetPhone: string;
    function GetNum_Hosted: string;
  end;

implementation

{ TUser }

constructor TUser.Create(sFirstName, sLastName, sPhone, sProfilePic, sBio, sNum_Hosted: string);
begin
  FProfilePic := sProfilePic;
  FBio := sBio;
  FFirstName := sFirstName;
  FLastName := sLastName; // Fixed typo in variable name
  FPhone := sPhone;
  FNum_Hosted := sNum_Hosted;
end;

function TUser.GetProfilePic: string;
begin
  Result := FProfilePic;
end;

function TUser.GetBio: string;
begin
  Result := FBio;
end;

function TUser.GetName: string;
begin
  Result := FFirstName;
end;

function TUser.GetPhone: string;
begin
  Result := FPhone;
end;

function TUser.GetNum_Hosted: string;
begin
  Result := FNum_Hosted;
end;


end.

内容的提问来源于stack exchange,提问作者Kyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:55:32