Delphi SQlite登录过程崩溃

Delphi SQlite登录过程崩溃,sqlite,delphi,Sqlite,Delphi,我一直在试图弄清楚为什么下面的登录身份验证过程不起作用。我有一个简单的数据库表,其中包含pupilID和password(在tblPupil中),它在编译时似乎连接正常,即过程连接,但当我运行过程登录时…程序似乎崩溃。事实上,我没有收到任何错误消息,这些消息可以进一步照亮我!这可能是数据库驱动程序的问题吗? (使用Delphi7、带有DevartSQLiteDirect驱动程序的SQLite数据库) 程序TForm1.连接; 开始 SQLConnection1.Params.Add('Datab

我一直在试图弄清楚为什么下面的登录身份验证过程不起作用。我有一个简单的数据库表,其中包含pupilID和password(在tblPupil中),它在编译时似乎连接正常,即过程连接,但当我运行过程登录时…程序似乎崩溃。事实上,我没有收到任何错误消息,这些消息可以进一步照亮我!这可能是数据库驱动程序的问题吗? (使用Delphi7、带有DevartSQLiteDirect驱动程序的SQLite数据库)

程序TForm1.连接;
开始
SQLConnection1.Params.Add('Database=C:\SQLite\PupilDatabase');
尝试
//建立连接。
SQLConnection1.Connected:=true;
标签4.标题:=“好!”;
除了
关于E:EDatabaseError do
ShowMessage('消息'+E.message'引发异常);
结束;
结束;
程序TForm1.UserLogin;
var QueryPass:string;
l计数:字符串;
续:布尔型;
开始
续:=假;
如果InputID.Text='',则
ShowMessage('无效的学生ID')
否则开始
续:=正确;
而cont=True do
开始
//随机查询
QueryPass:=“从TblPupil中选择密码,其中pupilID=+InputID.Text+”;”;
尝试
//将查询分配给对象SQLQuery1。
SQLQuery1.SQL.Text:=QueryPass;
SQLQuery1.open;
除了
关于E:Exception-do
ShowMessage('message:'+E.message引发的异常);
结束;
SQLQuery1.首先;
Lcount:=SQLQuery1.FieldValues['password'];
如果Lcount=InputPass.text,则
开始
形式1.隐藏;
表16.1显示;
结束
其他的
开始
ShowMessage(“错误”);
续:=假;
结束;
形式1.隐藏;
表16.1显示;
结束;
结束;
结束;

我认为您应该这样做(根据我在一个应用程序中使用的代码):

程序TForm4.advGlowButton1单击(发送方:ToObject);
开始
LOGIN\u QUERY.Active:=false;
LOGIN_QUERY.SQL.Clear;
LOGIN_QUERY.SQL.Add('select user,password,from user='+QuotedStr(cxlookupcombobox1.text)+'和password='+QuotedStr(cxTextEdit1.text)的用户);
登录_QUERY.Open;
如果登录名为_QUERY.FieldByName('Password')。关联字符串“”
然后是表格16。展示其他
ShowMessage(“错误的密码”);
结束;

虽然您的代码有点繁琐,但我不明白为什么您的表只包含pupilID和密码。是否也应该有一个学生的名字?

可能是因为form16尚未创建。然而,更重要的是,当delphi遇到异常时,您需要让它停止。我怀疑你不小心把它关掉了。 根据您的Delphi版本,它可能是 菜单/选项/调试器选项,然后选择停止Delphi异常


还要注意的是,在空数据集上“first”操作失败,因此为了防御,您应该在那里进行“bof”检查,以防输入无效。

您的查询毫无意义。正如现在编写的,它甚至不会编译(右侧有未终止的引号),更不用说执行了(因为“WHERE pupilID=+Input.Text+”是无效的SQL语法)

在您开始之前,要摆脱立即连接SQL的习惯,并学习使用参数化查询。这样做可以防止SQL注入,并允许数据库驱动程序正确地进行数据类型转换,并在需要时正确地引用值,这样您就不必这样做了

SQLQuery1.SQL.Text := 'SELECT password from TblPupil'#13 +
                      'WHERE pupilID = :pupilID';
SQLQuery1.ParamByName('pupilID').AsString := InputID.Text;
SQLQuery1.Open;
话虽如此,您的
UserLogin
过程中的其余代码也非常糟糕。它充满了不必要的变量,逻辑无效(不管用户名和密码是否匹配,最终都会隐藏Form1并显示Form6,这破坏了登录AFAICT的全部目的)。您可以尝试以下方法:

Procedure TForm1.UserLogin;
var 
  UserPass: string;
begin
  if InputID.Text = '' then
    raise Exception.Create('You must enter a Pupil ID.');

  SQLQuery1.SQL.Text := 'SELECT password from TblPupil'#13 +
                        'WHERE pupilID = :pupilID';
  SQLQuery1.ParamByName('pupilID').AsString := InputID.Text;
  try
    SQLQuery1.Open;
    if SQLQuery1.IsEmpty then
      raise Exception.Create('Invalid Pupil ID or password.');
    UserPass := SQLQuery1.FieldValues['password'];
  finally
    SQLQuery1.Close;
  end;

 if UserPass = InputPass.text then
 begin
     Form1.Hide;
     Form16.show;
  end
  else
    raise Exception.Create('Invalid Pupil ID or password.');
end;

当您单步执行
UserLogin
代码时,调试器会告诉您什么?只是输入错误??你的问题是否定的
QueryPass:=“从TblPupil中选择密码,其中pupilID=+InputID.Text+”
表示
pupilID
必须等于一个带加号的字符串
+
和一个文本
InputID.text
。我是舒尔,这不是你想要的。正确的查询应该如下所示:
QueryPass:=“从TblPupil中选择密码,其中pupilID=''”+InputID.Text+'';”
或如果字段pupilID是整数,则:
QueryPass:=“从TblPupil中选择密码,其中pupilID=”+InputID.Text+”;”你能查一下我最喜欢的密码吗;从用户中删除与您的应用程序一起使用?感谢您的回复…我目前正在根据您的回复重新处理解决方案。我将很快更新进度。谢谢
Procedure TForm1.UserLogin;
var 
  UserPass: string;
begin
  if InputID.Text = '' then
    raise Exception.Create('You must enter a Pupil ID.');

  SQLQuery1.SQL.Text := 'SELECT password from TblPupil'#13 +
                        'WHERE pupilID = :pupilID';
  SQLQuery1.ParamByName('pupilID').AsString := InputID.Text;
  try
    SQLQuery1.Open;
    if SQLQuery1.IsEmpty then
      raise Exception.Create('Invalid Pupil ID or password.');
    UserPass := SQLQuery1.FieldValues['password'];
  finally
    SQLQuery1.Close;
  end;

 if UserPass = InputPass.text then
 begin
     Form1.Hide;
     Form16.show;
  end
  else
    raise Exception.Create('Invalid Pupil ID or password.');
end;