4

这里的任何帮助都会很棒。

我正在尝试使用参数来动态更改“ORDER BY”

下面是我尝试过的代码,但尽管遵循了文档,但我仍然收到错误“[FIREDAC][PHYS][MYSQL] You have an error in your SQL syntax ... near "ORDER BY some_field" at line 4'

我已将 ParamCreate 设置为 True

我的数据库是 MySQL

FDQuery1.Close;
FDQuery1.SQL.Clear;
FDQuery1.SQL.Add('SELECT *');
FDQuery1.SQL.Add('FROM my_table');
FDQuery1.SQL.Add('LIMIT 1000');
FDQuery1.SQL.Add(':id');
FDQuery1.ParamByName('id').AsString := 'ORDER BY some_field';
FDQuery1.Open;
4

5 回答 5

8

您没有引用显示的异常消息。这是原始消息

[FireDAC][Phys][MySQL] 您的 SQL 语法有错误……''ORDER BY some_field''在第 4 行附近。

与您的引用进行比较

[FIREDAC][PHYS][MYSQL] 您的 SQL 语法有错误……"ORDER BY some_field"在第 4 行附近


为避免将来发生这种情况,只需在焦点异常窗口上按CTRL+ C,完整的消息就在剪贴板中,可以粘贴到任何你喜欢的地方


现在读到这里,错误现在很清楚了。

你期望得到这样的声明

SELECT *
FROM my_table
LIMIT 1000
ORDER BY some_field

但是使用参数你会得到下面的语句

SELECT *
FROM my_table
LIMIT 1000
'ORDER BY some_field'

这正是异常消息告诉您的内容。

只需使用上一条语句检查异常消息

...'ORDER BY some_field'在 4 号线附近。

...''ORDER BY some_field''在 4 号线附近。

作为结论,不可能使用参数更改语句本身。您只能将值作为语句的参数传递。

无论如何,正确的陈述应该是

SELECT *
FROM my_table
ORDER BY some_field
LIMIT 1000
于 2014-10-15T20:14:48.677 回答
8

不知道这是否有帮助。但是您可以使用 TFDQuery 的“宏”属性,例如由“:”标识的参数,宏由“!”标识,您也可以将宏和参数组合。Macros 属性几乎与 Params 属性一样工作。使用 TFDQuery.MacroByname 分配宏值,并使用 TFDQuery.MacroByname('MacroName').AsRaw 按原样分配字符串。

因此,您的查询应如下所示:

FDQuery1.Close;
FDQuery1.SQL.Text := 'SELECT * FROM !TABLE_NAME !WHERE_CLAUSE !ORDERBY_CLAUSE';

FDQuery.MacroByname('Table_name').AsRaw := 'my_table';
FDQuery.MacroByname('Where_clause').AsRaw := 'WHERE field1 = :ID_Value';
FDQuery.MacroByname('OrderBy_clause').AsRaw := 'ORDER BY field1';

FDQuery.ParamByname('ID_Value').AsInteger := 1;

FDQuery1.Open;

希望这可以帮助

于 2015-02-23T19:58:41.193 回答
3

你需要非常简单的 SQL 查询:

FDQuery1.Close;
FDQuery1.SQL.Text := 'SELECT * FROM my_table';
FDQuery1.Open;

要设置记录数的限制,您可以使用 FDQuery1 的属性:

FDQuery1.FetchOptions.RecsMax := 1000;

要对值进行排序,您可以使用

FDQuery1.IndexFieldNames = 'field_name'

或者

FDQuery1.IndexFieldNames = 'field_one_name;field_two_name'

而不是你的代码。

于 2014-11-20T14:11:31.317 回答
2

编辑:哦,我实际上并没有回答你的问题。因此,对于 FireDac,您只需将FDQuery1.IndexFieldNames属性设置为您要订购的字段的名称。无需关闭并重新打开您的查询,或更改 SQL。

上一个答案:您不能在参数中传递SQL代码[编辑:包括ORDER BY等],只能传递参数值,即整数、字符串等。这个原则非常重要,否则你可以传递例如

FDQuery1.ParamByName('id').AsString := '; TRUNCATE TABLE my_table';

然后执行您的查询将删除表中的所有内容,而不是执行它应该执行的操作。或者多做一些工作,您的相同查询可能会返回密码、信用卡号或数据库中的任何其他内容。这将是一个巨大的漏洞,被称为 SQL 注入。请参阅示例:

http://www.w3schools.com/sql/sql_injection.asp

http://sqlmap.org/

http://hackaday.com/2014/09/01/gaining-access-to-the-oculus-developer-database

于 2015-01-14T18:14:53.203 回答
1

RXLIB 具有此功能。它具有 MACRO 选项,您可以在其中编写如下代码:

选择 %fields_ from %table_ where %condition_ order by %order_

但它仅用于 qith BDE。

如果有人重写代码以使用 ADO 或 FIREDAC,那就太好了。

于 2014-11-19T11:12:41.980 回答