An toàn
query.SQL.Text := 'select * from table_name where name=:Name';
Mã này an toàn vì bạn đang sử dụng các tham số.
Các tham số luôn an toàn trước SQL-injection.
Không an toàn
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
Không an toàn vì Tên người dùng có thể là tên name; Drop table_name;
Dẫn đến truy vấn sau được thực thi.
select * from table_name where name=name; Drop table_name;
Ngoài ra Không an toàn
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
Bởi vì nó nếu tên người dùng là ' or (1=1); Drop Table_name; --
Nó sẽ dẫn đến truy vấn sau:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Nhưng mã này an toàn
var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Bởi vì IntToStr()
sẽ chỉ chấp nhận các số nguyên vì vậy không có mã SQL nào có thể được đưa vào chuỗi truy vấn theo cách này, chỉ các số (chính xác là những gì bạn muốn và do đó được phép)
Nhưng tôi muốn thực hiện những việc không thể thực hiện được với các tham số
Tham số chỉ có thể được sử dụng cho các giá trị. Chúng không thể thay thế tên trường hoặc tên bảng. Vì vậy, nếu bạn muốn thực hiện truy vấn này
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
Truy vấn đầu tiên không thành công vì bạn không thể sử dụng các tham số cho tên bảng hoặc trường.
Truy vấn thứ hai không an toàn nhưng là cách duy nhất có thể thực hiện điều này.
Làm cách nào để bạn giữ an toàn?
Bạn phải kiểm tra chuỗi tablename
chống lại một danh sách các tên đã được phê duyệt.
Const
ApprovedTables: array[0..1] of string = ('table1','table2');
procedure DoQuery(tablename: string);
var
i: integer;
Approved: boolean;
query: string;
begin
Approved:= false;
for i:= lo(ApprovedTables) to hi(ApprovedTables) do begin
Approved:= Approved or (lowercase(tablename) = ApprovedTables[i]);
end; {for i}
if not Approved then exit;
query:= 'SELECT * FROM '+tablename;
...
Đó là cách duy nhất để làm điều này mà tôi biết.
BTW Mã ban đầu của bạn có lỗi:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
Nên
query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
Bạn không thể có hai where
's trong một (con) truy vấn