如何在 delphi 中的 SQL(删除)语句中包含整数值
How to include an integer value in a SQL (Delete) statement in delphi
在数据库中,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;
的问题
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 是一个整数列而不是一个字符串。
因此,由于您的 ID 列是整数列类型,请改用此方法(但请参阅下文有关 Sql 注入的危险):
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 注入的影响(参见 https://en.wikipedia.org/wiki/SQL_injection),而您的做法是允许用户指定 [=49= 的一部分] 使用 InputQuery 然后将其与其他 DELETE 文本连接起来,则不是。事实上,将用户输入连接到 SQL 语句 正是 允许 Sql 注入攻击的东西 - 例如恶意用户可以添加另一个语句(或更多)到您正在构建的那个的末尾,例如DROP TABLE Employee
(或更糟)。当查询被参数化时,这种用户颠覆 Sql 语句的机会永远不会出现。
Fwiw,我个人不喜欢使用 TParameter Value
属性 的原因是它是一个变体,因此会破坏指定值的数据类型。
顺便说一句,iID
对于实际上是字符串的变量来说不是一个很好的名称。 'i' 前缀通常会让读者期待一个整数。
在数据库中,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;
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 是一个整数列而不是一个字符串。
因此,由于您的 ID 列是整数列类型,请改用此方法(但请参阅下文有关 Sql 注入的危险):
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 注入的影响(参见 https://en.wikipedia.org/wiki/SQL_injection),而您的做法是允许用户指定 [=49= 的一部分] 使用 InputQuery 然后将其与其他 DELETE 文本连接起来,则不是。事实上,将用户输入连接到 SQL 语句 正是 允许 Sql 注入攻击的东西 - 例如恶意用户可以添加另一个语句(或更多)到您正在构建的那个的末尾,例如DROP TABLE Employee
(或更糟)。当查询被参数化时,这种用户颠覆 Sql 语句的机会永远不会出现。
Fwiw,我个人不喜欢使用 TParameter Value
属性 的原因是它是一个变体,因此会破坏指定值的数据类型。
顺便说一句,iID
对于实际上是字符串的变量来说不是一个很好的名称。 'i' 前缀通常会让读者期待一个整数。