Question

I'm about ready to rip my hair out and take up poop flinging as a living!

I have a MySQL query which runs fine in 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 

But when I try to run this as a query in a SQLDataSet in Delphi

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;

I get an error

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

If anyone can offer any insight, I would be most appreciative.

EDIT:

I am using the MySQL server 5.5 and Delphi XE

What I am trying to do is this:

I have a tables as follows:

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       |                |
+--------------------+---------+------+-----+---------+----------------+

What I need to do is to "produce" a new profile which is the sum of a set of existing profiles. so, the data from the profiledata table must be summed where the ProfileID is included in the virtualprofile and the timestamp values are equal.

Was it helpful?

Solution

The Problem

So, the problem is this. The DBExpress driver provided with Delphi XE can only process Dynamic SQL queries, not MySQL Queries. Although Dynamic SQL is compatible with MySQL, it is not compatible the other way around.

Quoting from the MySQL Manual (sec 12.16.3):

In standard SQL, a query that includes a GROUP BY clause cannot refer to nonaggregated columns in the select list that are not named in the GROUP BY clause.

MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause.

The updated DBExpress driver included with Delphi XE3 includes specific support for MySQL code, and so this limitation is not applicable.

The Workaround

The solution to this problem is to create a view in MySQL server and to call it from Delphi using only Dynamic SQL compatible code. In the end the following workaround did the trick:

In 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

Then in Delphi

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

OTHER TIPS

You changed the name of the column here:

v.VirtualProfiles_id AS VProfileID

After that point, in most cases (the exception being those involving grouping or aggregation), you need to refer to the column by the new name. I think that's the case here.

Try changing your WHERE clause to use the alias instead:

WHERE v.VirtualProfiles_id = ' + InttoStr(5)

The problem is the compatibility between Mysql Types and Delphi types try to use Basics Types of delphi

In my case changing from

SELECT * FROM table_name WHERE column_name = 'VALUE';

to

SELECT * FROM table_name WHERE column_name LIKE 'VALUE';

solved the problem and return the same result.

I didn't dig dipper to figure it out what was happening, but it is a weird bug because it works fine with every other column except with a specific one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top