在数据库中,DoctorID是一个整数列。编辑后的“//”代码行都不起作用。如果有人能告诉我如何在SQL语句中正确指定整数值,我将非常感激。
procedure TForm1.btnDeleteDocClick(Sender: TObject);
var
iID : Integer;
begin
iID := StrToInt (InputBox('Delete Doctor','Please enter in your Doctor ID',''));
with dmHospital do
begin
qryDoctors.SQL.Clear;
//qryDoctors.SQL.Add('DELETE FROM Doctors WHERE DoctorID = iID ' ) ;
//qryDoctors.SQL.Add('DELETE FROM Doctors WHERE DoctorID = ' + QuotedStr(iID));
qryDoctors.ExecSQL;
qryDoctors.SQL.Clear;
qryDoctors.SQL.Add('SELECT * FROM Doctors');
qryDoctors.Open;
end;
end;
答案 0 :(得分:5)
的问题
qryDoctors.SQL.Add('DELETE FROM Doctors WHERE DoctorID = iID ' )
是它没有将变量iID
的值引入DELETE语句,因为你显然已经收集了它。
同样,
的问题qryDoctors.SQL.Add('DELETE FROM Doctors WHERE DoctorID = ' + QuotedStr(iID))
是它用引号包围iID的值,因此执行DELETE语句的Sql引擎实际看到的是
DELETE FROM Doctors WHERE DoctorID = '99'
但是DoctorID是一个Integer列而不是一个字符串。
因此,由于您的ID列是整数列类型,请尝试这样做(但请参阅下面有关Sql Injection的危险):
qryDoctors.SQL.Add('DELETE FROM Doctors WHERE DoctorID = ' + iID);
喵,你不需要围绕整数值的引号。
DELETE
语句的参数化版本将是更好的解决方案:
qryDoctors.SQL.Text := 'DELETE FROM Doctors WHERE DoctorID = :DoctorID';
qryDoctors.ParamByName('DoctorID').Value := StrToInt(iID);
这个更好的一个原因是它不受Sql Injection(参见https://en.wikipedia.org/wiki/SQL_injection)的影响,而你的做法是允许用户使用InputQuery指定部分SQL然后将其与其他DELETE文本,不是。实际上,将用户输入连接到SQL语句完全允许Sql Injection漏洞利用的东西 - 例如,恶意用户可以将另一个语句(或更多)添加到您的那个语句的末尾建筑,例如DROP TABLE Employee
(或更糟)。当查询参数化时,这种用户颠覆Sql语句的机会永远不会出现。
Fwiw,我个人不喜欢使用TParameter的Value
属性的原因是它是一个变体,所以颠覆了指定值的数据类型。
顺便说一下,iID
对于一个实际上是字符串的变量来说不是一个很好的名字。 'i'前缀通常会引导读者期待一个整数。