【问题标题】:How to check through Delphi if a record exist in MS Access(Database)?如果MS Access(数据库)中存在记录,如何通过Delphi检查?
【发布时间】:2013-09-29 12:47:02
【问题描述】:

您好,我有一个 Delphi 7 项目任务,我们需要在其中包含一个登录系统。我有一个注册页面,其中数据进入 Access 中的一个表。现在当用户需要登录时,它需要检查他/她的信息是否存在,然后他将被授予进一步的权限,但不知道该怎么做。

【问题讨论】:

  • 先试后问。在此过程中,您必须至少有一些东西
  • 当然,您可以搜索如何将 Delphi 和 ADO 与 Access 一起使用,并且至少自己先想出某种的努力。至少是谷歌的“delphi 数据库教程”。

标签: delphi login-system


【解决方案1】:

自从我升级到 2005 和更高版本已经有一段时间了,所以我无法在 Delphi 7 上对其进行测试,但至少在 Delphi 2005 及以上版本中,您可以使用以下过程:

USES {$IFDEF UseParmsEvenThoughTheyAreNotNecessary } DB {$ELSE } StrUtils {$ENDIF } ,ADODB;

FUNCTION CanLogIn(CONST UserName,Password : STRING ; CONST AccessDatabaseFile,TableName,UserField,PasswordField : STRING) : BOOLEAN;
  VAR
    Connection : TADOConnection;
    DataSet    : TADODataSet;

  FUNCTION AccessConnStr(CONST FileName : STRING) : STRING;
    BEGIN
      {$IFDEF CPUX64 }
        Result:='Provider=Microsoft.ACE.OLEDB.12.0;Data source='+FileName
      {$ELSE }
        Result:='Provider=Microsoft.Jet.OLEDB.4.0.0;Data Source='+FileName
      {$ENDIF }
    END;

  {$IFNDEF UseParmsEvenThoughTheyAreNotNecessary }
    FUNCTION QuotedStr(CONST STR : STRING) : STRING;
      BEGIN
        Result:=''''+ReplaceStr(STR,'''','''''')+''''
      END;
  {$ENDIF }

  BEGIN
    Connection:=TADOConnection.Create(NIL);
    TRY
      Connection.ConnectionString:=AccessConnStr(AccessDatabaseFile);
      TRY
        Connection.Connected:=TRUE;
        TRY
          DataSet:=TADODataSet.Create(NIL);
          TRY
            DataSet.CommandType:=cmdText;
            {$IFDEF UseParmsEvenThoughTheyAreNotNecessary }
              DataSet.ParamCheck:=TRUE;
              DataSet.Parameters.CreateParameter('UserName',ftString,pdInput,80,UserName);
              DataSet.Parameters.CreateParameter('Password',ftString,pdInput,80,Password);
              DataSet.CommandText:='SELECT * FROM ['+TableName+'] WHERE ['+UserField+']=:UserName AND ['+PasswordField+']=:Password';
            {$ELSE }
              DataSet.ParamCheck:=FALSE;
              DataSet.CommandText:='SELECT * FROM ['+TableName+'] WHERE ['+UserField+']='+QuotedStr(UserName)+' AND ['+PasswordField+']='+QuotedStr(Password);
            {$ENDIF }
            TRY
              DataSet.Open;
              TRY
                Result:=NOT DataSet.EOF
              FINALLY
                DataSet.Close
              END
            EXCEPT
              Result:=FALSE
            END
          FINALLY
            DataSet.Free
          END
        FINALLY
          Connection.Close
        END
      EXCEPT
        Result:=FALSE
      END
    FINALLY
      Connection.Free
    END
  END;

参数:

UserName = Name of the user attempting to log in
Password = Password of the user
AccessDatabaseFile = The access database file
TableName = The name of the table containing the UserName/Password for allowed users
UserField = The name of the field in the above table that contains the user name
PasswordField = The name of the field in the above table that contains the password for the user

如果发生异常(未找到文件、错误的表名/字段名或您有什么),该函数会捕获这些并返回 FALSE。只有当整个函数都成功并且在表中找到了正确密码的用户时,函数才返回TRUE。

【讨论】:

  • 即使是这样,使用参数始终是正确的做法。作为额外的奖励,您不必将 QuotedStr 搞得一团糟! (仅供参考 QuotedStr 是 Delphi 中存在的一个函数)
  • 再一次:给我允许 SQL 注入的用户名和密码的值。我过去挑战过的任何人都无法做到这一点,除非得到证明,否则我坚持我的主张,即这是不可能的......
  • 一些 cmets:在 Delphi 中有一个内置的 QuotedStr 函数。上面的代码不受 SQL 注入的影响,因为它不使用 \' 来转义单引号。在 NON-Unicode Delphi(例如 7)中使用参数将破坏 Unicode (WideString) 参数。
  • @HeartWare 再次,我并不是说您的代码存在注入漏洞,但是您在“哦,我确定此查询不可注入”和“现在我必须使用参数因为安全问题”?如果您总是使用参数,则不必向自己提出这个问题。恕我直言,这是一种糟糕的编码做法(问问索尼和许多其他被黑的公司;))
  • @whosrdaddy,告诉我。但是我们中的一些人没有时间/$ 将大型应用程序切换到现代 Delphi 版本:/ 无论如何,如果 Unicode 不是问题,我肯定会在这种情况下使用参数,这始终是一个好习惯。但是由于未使用参数而对答案自动投票是错误的恕我直言。特别是因为您无法证明上述答案受到 SQL 注入的影响。 HeartWare 可以编辑他的答案并提出替代方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
相关资源
最近更新 更多