delphi - AdoQuery 无法使用 SHOW : command

标签 delphi

我正在撕扯我的头发!!

即使是像这样简单的事情:

procedure MyAdoQueryTest();
   const MYSQL_CONNECT_STRING='Driver={MySQL ODBC 5.1 Driver};Server=%s;Port=3306;Database=%s;User=%s;Password=%s;Option=3;';

   var   AdoConnection  : TADOConnection;
         ADOQuery : TADOQuery;
         Param    : TParameter;
begin
   AdoConnection := TADOConnection.Create(Nil);
   AdoConnection.ConnectionString := Format(MYSQL_CONNECT_STRING,['localhost',
                                                                  'mysql',
                                                              'root',
                                                              '']);
    AdoConnection.LoginPrompt := False;
    AdoConnection.Connected := True;

   ADOQuery := TADOQuery.Create(Nil);
   ADOQuery.Connection := AdoConnection;
   ADOQuery.Sql.Clear();
   ADOQuery.SQl.Add('SHOW :what_to_show');

   Param := ADOQuery.Parameters.ParamByName('what_to_show');
   Param.DataType := ftString;
   Param.Value := 'databases';

   ADOQuery.Prepared := true;
   ADOQuery.Active := True;
end;

(顺便说一句,我真的需要使用“Param”变量和 3 个语句,还是可以只使用“ADOQuery.Parameters.ParamByName('what_to_show').Value := 'databases';?”

无论如何,当我运行它时,我在 ADOQuery.SQl.Add('SHOW :what_to_show'); 处遇到异常,其中显示“参数类型错误,超出了可接受的范围”范围或相互冲突”。

我想做的是创建 2 个中心函数:一个接受并执行任何不会返回任何数据的 SQL 语句(例如 INSERT INTO),另一个会接受并执行任何数据(例如 SELECT)。

我目前仅使用 AdoConnection,但现在尝试使用 AdoQuery,因为我想参数化我的 SQL 语句以处理带引号的字符串。

我可以有halpz吗?

最佳答案

错误在这里:

ADOQuery.SQl.Add('SHOW :what_to_show');

:Param 只能用于值,不能用于动态列/关键字/表/数据库名称。
这是因为,如果它像这样工作,您将面临 SQL 注入(inject)风险,具体取决于参数的内容。

为了解决这个问题,您必须将 what_to_show 内容注入(inject)到 SQL 字符串中。

像这样:

var
  what_to_show: string;
begin
  ....
  what_to_show:= 'tables';
  ADOQuery.SQL.Text:= ('SHOW '+what_to_show);
  ....

现在就可以了。

enter image description here 警告
确保测试您注入(inject) SQL 的所有内容,以防止用户将其 SQL 代码注入(inject)您的查询中。
参数可以防止 SQL 注入(inject),但由于您不能在此处使用它们,因此您需要根据预先批准的值列表来检查它们。例如包含所有允许的内容的 stringlist
转义或使用特殊字符是没有用的。

安全注入(inject)示例代码

var
  what_to_show: string;
  i: integer;
  inputapproved: boolean;
begin
  ....
  what_to_show:= lower(trim(someinput));
  i:= 0;
  inputapproved:= false;
  while (i < WhiteList.count) and not(inputapproved) do begin
    inputapproved:= ( what_to_show = lower(Whitelist[i]) );
    Inc(i);
  end; {while}
  if inputapproved then ADOQuery.SQL.Text:= ('SHOW '+what_to_show);
  ....

关于delphi - AdoQuery 无法使用 SHOW : command,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6241150/

相关文章:

delphi - 如何继承 TcxGridDBTableView 并使用它而不丢失我的 GUI 设置并将其安装为组件?

Delphi在设计时使用自定义控件,无需封装

delphi - 如何使用Delphi检查进程是否正在运行?

delphi - 为什么如果通过变量向数据库添加值,则会添加 “ADOQuery1”,如果直接添加,则会添加正确的值?

delphi - Delphi简单数据类型等效

delphi - 如何获取列出的网页的所有元素Id?

Delphi + Binance Api + 限价单问题 无效签名

delphi - 将 SVG 图形加载到 FireMonkey 应用程序中需要采取什么方法?

c++ - Delphi 中 C+ +'s "unsigned char 的等价物是什么?

德尔福64位?