'Delphi中的where子句中的未知列,但不是MySQL

时间:2012-12-06 09:43:09

标签: mysql delphi delphi-xe dbexpress dbx

我准备把我的头发撕掉,然后把大便扔掉作为生活!

我有一个在MySQL中运行良好的MySQL查询

SELECT 
    p.ID AS DataID, 
    p.timestamp AS Timestamp, 
    sum(p.Value * v.Factor) AS Value,
    v.VirtualProfiles_id AS VProfileID 
FROM 
    profiledata p 
JOIN 
    profilevirtualjoin v 
ON 
    p.Profile_ID=v.Profile_ID 
WHERE 
    v.VirtualProfiles_id = 5
GROUP BY 
    v.Profile_ID, 
    p.timestamp 

但是当我尝试在Delphi的SQLDataSet中将其作为查询运行时

SQLDataSet2.Active := False;
SQLDataSet2.CommandText := 'SELECT p.ID AS DataID, p.timestamp AS Timestamp, sum(p.Value * v.Factor) AS Value,' +
   'v.VirtualProfiles_id AS VProfileID FROM profiledata p JOIN profilevirtualjoin v ON ' +
   'p.Profile_ID=v.Profile_ID WHERE v.VirtualProfiles_id = ' + InttoStr(5)
   +' GROUP BY v.Profile_ID, p.timestamp';
SQLDataSet2.Active := True;

我收到错误

First chance exception at $765BC41F. Exception class TDBXError with message 'Unknown column 'v.VirtualProfiles_id' in 'where clause''. Process EMVS.exe (7556)

如果有人能提供任何见解,我将非常感激。

编辑:

我正在使用MySQL服务器5.5和Delphi XE

我想做的是:

我有一张表格如下:

Profile:
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| ID          | int(11)      | NO   | PRI | NULL    | auto_increment |
| Designation | varchar(255) | YES  |     | NULL    |                |
| Description | text         | YES  |     | NULL    |                |
| UnitID      | int(11)      | NO   | PRI | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

profiledata
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| ID         | int(11)  | NO   | PRI | NULL    | auto_increment |
| TimeStamp  | datetime | YES  |     | NULL    |                |
| Value      | double   | YES  |     | NULL    |                |
| Profile_ID | int(11)  | NO   | PRI | NULL    |                |
+------------+----------+------+-----+---------+----------------+

Virtualprofiles
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| Designation | varchar(45)  | NO   |     | NULL    |                |
| Description | varchar(255) | YES  |     | NULL    |                |
| Unit_ID     | int(11)      | NO   | PRI | 0       |                |
+-------------+--------------+------+-----+---------+----------------+

profilevirtualjoin
+--------------------+---------+------+-----+---------+----------------+
| Field              | Type    | Null | Key | Default | Extra          |
+--------------------+---------+------+-----+---------+----------------+
| id                 | int(11) | NO   | PRI | NULL    | auto_increment |
| VirtualProfiles_id | int(11) | NO   | PRI | NULL    |                |
| Profile_ID         | int(11) | NO   | PRI | NULL    |                |
| Factor             | double  | NO   |     | 1       |                |
+--------------------+---------+------+-----+---------+----------------+

我需要做的是“生成”一个新的配置文件,它是一组现有配置文件的总和。因此,必须将profiledata表中的数据求和,其中ProfileID包含在virtualprofile中,且时间戳值相等。

4 个答案:

答案 0 :(得分:4)

问题

所以,问题是这个。 Delphi XE 提供的DBExpress驱动程序只能处理动态SQL查询,而不能处理MySQL查询。尽管Dynamic SQL与MySQL兼容,但它与其他方式不兼容。

引自MySQL手册(第12.16.3节):

  

在标准SQL中,包含GROUP BY子句的查询不能引用选择列表中未在GROUP BY子句中命名的非聚合列。

     

MySQL扩展了GROUP BY的使用,因此选择列表可以引用未在GROUP BY子句中命名的非聚合列。

Delphi XE3 附带的更新DBExpress驱动程序包含对MySQL代码的特定支持,因此此限制不适用。

解决方法

此问题的解决方案是在MySQL服务器中创建一个视图,并仅使用与动态SQL兼容的代码从Delphi调用它。最后,下面的解决方法可以解决这个问题:

在MySQL中:

CREATE VIEW `VirtualProfileData` AS
SELECT 
    p.ID AS DataID, 
    p.timestamp AS Timestamp, 
    sum(p.Value * v.Factor) AS Value,
    v.VirtualProfiles_id AS VProfileID 
FROM 
    profiledata p 
JOIN 
    profilevirtualjoin v 
ON 
    p.Profile_ID=v.Profile_ID 
GROUP BY 
    v.Profile_ID, 
    p.timestamp

然后在Delphi

SQLDataSet2.Active := False;
SQLDataSet2.CommandText := 'SELECT * FROM VirtualProfileData WHERE VProfileID = ' + InttoStr(5);
SQLDataSet2.Active := True;

答案 1 :(得分:1)

您在此处更改了列的名称:

v.VirtualProfiles_id AS VProfileID

在此之后,在大多数情况下(例外是涉及分组或聚合的那些),您需要通过新名称引用该列。我认为就是这种情况。

尝试更改WHERE子句以改为使用别名:

WHERE v.VirtualProfiles_id = ' + InttoStr(5)

答案 2 :(得分:0)

问题是Mysql类型和Delphi类型之间的兼容性尝试使用基础知识类型的delphi

答案 3 :(得分:0)

以我为例,

SELECT * FROM table_name WHERE column_name = 'VALUE';

SELECT * FROM table_name WHERE column_name LIKE 'VALUE';

解决了问题并返回相同的结果。

我没有挖出北斗来弄清楚发生了什么,但这是一个奇怪的错误,因为它与除特定列之外的所有其他列均适用。