1

我正在使用 MS Access 数据库,表中有以下列Admins

Column        Type
======        ====
Name          Text 
Surname       Text 
Dateadded     Date/time 
Adminnumber   Number(long integer) 
Password      Text 
ID type       Autonumber  (Not sure if ID is relevant) 

这是我的代码,但它一直给我一个语法错误。

ADOquery1.Active := false;
adoquery1.sql.Text := 'insert into Admins(Name, surname, Adminnumber, Dateadded,password)Values('''+edit11.Text+''', '''+edit12.text+''', '''+edit13.Text+''', '''+edit14.Text+''', '''+edit15.text+''')';
ADOquery1.ExecSQL;
Adoquery1.SQL.Text := 'select * from Admins';
ADOquery1.Active := true;

我已经尝试了一天来弄清楚,但无论我使用什么代码,它都是同样的错误。错误是

项目 project1.exe 引发异常类 eoleException,并带有消息“INSERT INTO 语句中的语法错误”。

我也试过:

ADOquery1.SQL.Add('Insert into admins');
ADOquery1.SQL.Add('(Name , Surname, Dateadded, Adminnumber, Password)');  
ADOquery1.SQL.Add('Values :Name, :Surname, :Dateadded, :adminnumber :Password)');
ADOquery1.Parameters.ParamByName('Name').Value := edit11.Text;
ADOquery1.Parameters.ParamByName('Surname').Value := edit12.Text;
ADOquery1.Parameters.ParamByName('Dateadded').Value := edit13.Text;
ADOquery1.Parameters.ParamByName('Password').Value := edit14.Text;
ADOquery1.Parameters.ParamByName('Adminnumber').Value := edit15.Text;
ADOquery1.ExecSQL;
ADOquery1.SQL.Text := 'Select * from admins';
ADOquery1.Open ;

但是这段代码给了我 from 子句的问题

4

1 回答 1

10

问题是Name(并且可能Password)是 MS Access 中的保留字。对于列名来说,这是一个糟糕的选择,但如果您必须使用它,您应该通过将其括在方括号 ( []) 中来对其进行转义。您的语句后还缺少左括号 ( () ,参数后缺少逗号。VALUES:adminnumber

ADOquery1.SQL.Add('Insert into admins');
ADOquery1.SQL.Add('([Name] , [Surname], [Dateadded], [Adminnumber], [Password])');  
ADOquery1.SQL.Add('Values (:Name, :Surname, :Dateadded, :adminnumber, :Password)');
ADOquery1.Parameters.ParamByName('Name').Value := edit11.Text;
ADOquery1.Parameters.ParamByName('Surname').Value := edit12.Text;
ADOquery1.Parameters.ParamByName('Dateadded').Value := edit13.Text;
ADOquery1.Parameters.ParamByName('Password').Value := edit14.Text;
ADOquery1.Parameters.ParamByName('Adminnumber').Value := edit15.Text;
ADOquery1.ExecSQL;
ADOquery1.SQL.Text := 'Select * from admins';
ADOquery1.Open;

(正如您在问题的评论中所说,错误不能四处移动。唯一可能导致问题的行是该ADOQuery1.ExecSQL;行,因为它是唯一执行该INSERT语句的行。任何其他行都不可能引发异常。)

您应该在此处进行一些对代码的可维护性非常重要的更改。

首先,立即改掉使用默认控件名称的习惯,尤其是那些您以后需要从代码中访问的名称。Name您可以通过更改对象检查器中控件的属性来更改名称。

在代码中使用NameEdit.Text比在使用中容易得多Edit1.Text,尤其是在您使用Edit14. 如果改为Edit14命名会更清楚PasswordEdit,并且您会很高兴从现在起六个月后您必须更改代码。

其次,您应该避免使用在使用ParamByName().Value. 当您分配给text列时它工作正常,但当类型不是文本时(例如使用日期或数字时)就不是很好。在这些情况下,您应该在进行赋值之前转换为正确的数据类型,以确保它正确完成。

ADOQuery1.ParamByName('DateAdded').Value := StrToDate(DateEdit.Text);
ADOQuery1.ParamByName('AdminNumber').Value := StrToInt(AdminNum.Text);

最后,您永远不应该使用字符串连接,例如 'SOME SQL ''' + Edit1.Text + ''','''。这可能会导致称为SQL 注入的严重安全问题,它可能允许恶意用户删除您的数据、删除表或重置用户 ID 和密码,并允许他们自由访问您的数据。谷歌搜索会找到大量关于它可以创建的漏洞的信息。您甚至不应该在您认为安全的代码中执行此操作,因为将来事情可能会发生变化,或者您可能会遇到心怀不满的员工,决定在退出时引发问题。

例如,如果用户决定放入John';DROP TABLE Admins;edit14的应用程序,并且您ExecSQL使用该 SQL 调用,您将不再有一个Admins表。如果他们改为使用会发生什么John';UPDATE Admins SET PASSWORD = NULL;?您现在没有任何管理员用户的密码。

于 2013-09-05T00:35:07.927 回答