I'm developing using PHP since several years now.
But today I blocked on a problem I cannot explain, it's a very simple concatenation but it's result is bad (missing characters at the end of resulting string);
Here is the code:
$select = $this -> phpSqlCreator -> processSELECT2($this -> phpSqlParser -> parsed);
$from = $this -> phpSqlCreator -> processFROM2($this -> phpSqlParser -> parsed['FROM']);
$where = $this -> whereString;
$sql = $select . ' ' . $from . ' ' . $where;
When I debug this code here is what I see.
The $select variable contains this string :
SELECT DISTINCT t.id as "t.id",t.creation_date as "t.creation_date",t.default_language_code as
"t.default_language_code",t.name as "t.name",t.description as "t.description",t.document_store_path as
"t.document_store_path",t.type as "t.type",t.left_value as "t.left_value",t.right_value as "t.right_value",t.event_id as
"t.event_id",t.parent_id as "t.parent_id",t2.id as "t2.id",t2.creation_date as
"t2.creation_date",t2.default_language_code as "t2.default_language_code",t2.name as "t2.name",t2.description
as "t2.description",t2.document_store_path as "t2.document_store_path",t2.type as "t2.type",t2.left_value as
"t2.left_value",t2.right_value as "t2.right_value",t2.event_id as "t2.event_id",t2.parent_id as "t2.parent_id"
Then, the $from variable contains this string :
FROM team t , (SELECT t.* FROM team t LEFT JOIN team_role tr ON (t.id = tr.team_id) WHERE
tr.participant_id = ? UNION SELECT t.* FROM team t LEFT JOIN team_role tr ON (t.id = tr.team_id) LEFT JOIN
unit_role ur ON (tr.unit_id = ur.unit_id) WHERE ur.participant_id = ?) as dt LEFT JOIN team t2 ON ("t.parent_id" = t2.id)
The $where variable contains :
WHERE t.left_value < dt.left_value and t.right_value > dt.right_value and t.event_id = dt.event_id
The $sql variable contains :
SELECT DISTINCT t.id as "t.id",t.creation_date as "t.creation_date",t.default_language_code as
"t.default_language_code",t.name as "t.name",t.description as "t.description",t.document_store_path as
"t.document_store_path",t.type as "t.type",t.left_value as "t.left_value",t.right_value as "t.right_value",t.event_id as
"t.event_id",t.parent_id as "t.parent_id",t2.id as "t2.id",t2.creation_date as
"t2.creation_date",t2.default_language_code as "t2.default_language_code",t2.name as "t2.name",t2.description
as "t2.description",t2.document_store_path as "t2.document_store_path",t2.type as "t2.type",t2.left_value as
"t2.left_value",t2.right_value as "t2.right_value",t2.event_id as "t2.event_id",t2.parent_id as "t2.parent_id" FROM
team t , (SELECT t.* FROM team t LEFT JOIN team_role tr ON (t.id = tr.team_id) WHERE tr.participant_id = ?
UNION SELECT t.* FROM team t LEFT JOIN team_role tr ON (t.id = tr.team_id) LEFT JOIN unit_role ur ON
(tr.unit_id = ur.unit_id) WHERE ur.participant_id = ?) as dt LEFT JOIN team t2 ON (
The concatenation is very simple but does not work, the end of the $from string variable is missing and the full content of the $where string variable is also missing. I do not understand because the code is very simple.
Furthermore, this peace of code is thorougly executed by a set of automatic unit tests. It's very strange because when the code is executed using PHPUnit (so PHP Cli) the result of the concatenation is good (all our tests are successful).
This concatenation problem is only encountered when the code is executed inside our Web application (standard Apache 2.2.22 + PHP 5.3.13 settings on a Windows 8 machine).
Do you know what could cause this very strange problem? A PHP Setting? An PHP bug with the 5.3.13 version of PHP? Strange characters I do not see in the strings when I'm debugging? Something obvious I didn't see because I'm too tired tonight?
Obviously $sql is operating with a limit of 1024 characters. Either some program is storing something erroneously at the next address, or the $sql variable has a size limitation set somewhere.
From what I can see, in php , a string can be as large as 2GB. There is a memory_limit directive in the php.ini configuration file, but I can't imagine that you have that set to 1024 bytes (1K)
Hi zipzip and thanks for your response.
I finally found that the concatenation was good and that it was my IDE Eclipse which didn't show all the characters into my string.
More info can be found here : http://www.eclipse.org/forums/index.php/m/492856/
So my problem wasn't a problem.
Thanks a lot.
Baptiste
Related
1. Summarise the problem
Our company has been using this system for a long time and people feel huge system slowdown. I can't rewrite code because its super hardcoded and too many files to do so.
Few months ago we saw that one query takes about 170 s to execute.
My workaround was add LIMITS to each query and from 170s it went down to 2-3s. But last week i saw that code now takes about 5-25 sec.
Also this system is on php 5.2. Its basically impossible to upgrade code to work for 5.6
3 people was rewriting this code and after 8 hour we managed to make to login page.
Indexing is limited because most of database info have strings rather than integer.
2. Provide background including what you've already tried
What i tried:
- Adding limits by default 300, also users can change this limit.
- Migrating server to better hardware.
- Giving more RAM (10gb now) and two virtual CPU.
- Migrating from local storage to network (better performance at this moment).
3. Show some code
SELECT pastabos_apskaitininkui,
uzdaviniai.pakr_salis,
uzdaviniai.iskr_salis,
uzdaviniai.id AS uzdavinio_id,
salys.salis AS muitines_salis,
uzdaviniai.pakr_regionas,
uzdaviniai.iskr_regionas,
uzdaviniai.pakr_miestas,
uzdaviniai.iskr_miestas,
uzdavinio_priekaba,
priekabos.tipas AS priekabos_tipas,
uzdaviniai.kas_sukure_skyrius,
uzdaviniai.kam_sukure_skyrius,
uzdaviniai.kas_sukure_vadyb,
uzdaviniai.kam_sukure_vadyb,
uzdav_users.vardas_sutr AS uzdav_user_vardas,
pakrov_salis.sutrumpinimas AS uzdav_pakr_salis,
iskrov_salis.sutrumpinimas AS uzdav_iskr_salis,
uzdaviniai.pasikrovimo_data AS uzd_pasikrovimo_data,
uzdaviniai.pristatymo_data AS uzd_pristatymo_data,
uzdaviniai.pastabos,
suma_vykdytojui_valiuta,
vykdytojui_valiuta,
uzdaviniai.eil_nr,
uzdaviniai.statusas,
uzdaviniai.statusas_baigtas_ranka,
keliones_lapas.reiso_nr,
keliones_lapas.masina,
keliones_lapas.masinos_id,
keliones_lapas.priekabos_nr,
keliones_lapas.priekabos_id,
keliones_lapas.priekabos2_nr,
keliones_lapas.reiso_pavadinimas,
keliones_lapas.vykdytojo_tipas,
keliones_lapas.vykdytojo_imone,
keliones_lapas.atvykimo_data,
keliones_lapas.vairuotojas,
keliones_lapas.vairuotojas2,
keliones_lapas.vairuotojas3,
keliones_lapas.vairuotojas4,
keliones_lapas.marsrutas,
klientai.firmos_pavadinimas AS uzsakovas,
uzsakovo_uzs_nr,
valiutos.valiuta AS frachto_valiuta,
uzsakymas.vadybininkas,
uzsakymas.skyrius,
uzsakymas.frachtas_suma,
uzsakymas.pavadinimas,
uzsakymas.uzsakymo_id,
uzsakymas.reg_data,
uzsakymas.pastabos AS uzs_pastabos,
uzsakymas.statusas AS uzsakymo_statusas,
sask_ist.serija,
sask_ist.sask_nr,
sask_ist.id AS sask_id,
sask_ist.suma,
sask_ist.valiuta,
sask_ist.kursas AS sask_ist_kursas,
sask_ist.apmoketi_iki,
sask_ist.atidejimas,
issiuntimo_data,
sask_ist_apmokejimas.suma AS ist_apm_suma,
sask_ist_apmokejimas.valiuta AS ist_apm_valiuta,
sask_ist_apmokejimas.kursas AS ist_apm_kursas,
sask_ist_apmokejimas.id AS ist_apm_id,
klientu_pakr_vietos.pavadinimas AS muitines_pavadinimas,
klientu_pakr_vietos.miestas AS muitines_miestas,
klientu_pakr_vietos.adresas AS muitines_adresas,
kokio_krovinio_dalis,
krovinys_konsoliduotas,
kroviniu_tipai.pavadinimas AS krovinio_pavadinimas,
kroviniai.pasikrovimo_data,
kroviniai.pristatymo_data,
kroviniai.uzsakovo_krovinio_nr,
kroviniai.id AS krovinio_id,
svoris_t,
ldm,
turis,
paleciu_skaicius,
vnt,
temperature,
kroviniai.konteinerio_nr,
kroviniai.pakr_vietos_id AS kr_pakr_vietos_id,
kroviniai.iskr_vietos_id AS kr_iskr_vietos_id,
kroviniai.pakr_salis AS kr_pakr_salis,
kroviniai.iskr_salis AS kr_iskr_salis,
kroviniai.pakr_miestas AS kr_pakr_miestas,
kroviniai.pakr_regionas AS kr_pakr_regionas,
kroviniai.iskr_regionas AS kr_iskr_regionas,
kroviniai.iskr_miestas AS kr_iskr_miestas,
kroviniai.ismuitinimo_data AS ismuitinimo_data,
kroviniai.uzmuitinimo_data AS uzmuitinimo_data,
kroviniai.pasienio_postas AS pasienio_postas,
kroviniai.ismuitinimo_vieta AS ismuitinimo_vieta,
statusai.pavadinimas AS st_pavadinimas,
st_uzsakymai.id AS st_id,
st_salys.salis AS st_salis,
st_uzsakymai.data AS st_data,
st_uzsakymai.laikas AS st_laikas,
st_uzsakymai.ivykio_pastabos_sutr AS st_pastabos_sutr,
st_uzsakymai.ivykio_pastabos AS st_pastabos,
st_keliones_lapas.reiso_pavadinimas AS st_reiso_pav,
vairuotojai.vardas AS sq_vardas,
priekabos.masinos_nr AS sq_priekaba
FROM uzdaviniai
LEFT JOIN priekabos
ON priekabos.id = uzdaviniai.uzdavinio_priekaba
LEFT JOIN users AS uzdav_users
ON uzdav_users.id = uzdaviniai.kam_sukure_vadyb
LEFT JOIN salys AS pakrov_salis
ON pakrov_salis.id = uzdaviniai.pakr_salis
LEFT JOIN salys AS iskrov_salis
ON iskrov_salis.id = uzdaviniai.iskr_salis
LEFT JOIN uzsakymas
ON uzdaviniai.uzsakymo_id = uzsakymas.uzsakymo_id
LEFT JOIN uzd_kur_vykdytas
ON uzdaviniai.id = uzd_kur_vykdytas.uzdavinio_id
LEFT JOIN keliones_lapas
ON keliones_lapas.reiso_nr = uzd_kur_vykdytas.reiso_nr
LEFT JOIN st_uzsakymai
ON st_uzsakymai.uzdavinio_id = uzdaviniai.id
LEFT JOIN statusai
ON statusai.id = st_uzsakymai.statuso_id
LEFT JOIN salys AS st_salys
ON st_salys.id = st_uzsakymai.salis
LEFT JOIN keliones_lapas AS st_keliones_lapas
ON st_keliones_lapas.reiso_nr = st_uzsakymai.reiso_nr
LEFT JOIN vairuotojai
ON vairuotojai.id = keliones_lapas.vairuotojas
LEFT JOIN sask_ist_uz_ka
ON sask_ist_uz_ka.uzsakymo_id = uzsakymas.uzsakymo_id
LEFT JOIN sask_ist
ON sask_ist.id = sask_ist_uz_ka.sask_id
LEFT JOIN sask_ist_apmokejimas
ON sask_ist.id = sask_ist_apmokejimas.sask_id
LEFT JOIN uzsakymo_kroviniai
ON uzsakymas.uzsakymo_id = uzsakymo_kroviniai.uzsakymo_id
LEFT JOIN kroviniai
ON kroviniai.id = uzsakymo_kroviniai.krovinio_id
LEFT JOIN klientu_pakr_vietos
ON klientu_pakr_vietos.id = kroviniai.ismuitinimo_vieta
LEFT JOIN klientu_pakr_vietos AS iskr_vietos_uzd
ON iskr_vietos_uzd.id = uzdaviniai.pakr_vietos_id
LEFT JOIN salys
ON salys.id = klientu_pakr_vietos.salis
LEFT JOIN cmr_kroviniai
ON kroviniai.id = cmr_kroviniai.krovinio_id
LEFT JOIN cmr
ON cmr.id = cmr_kroviniai.cmr_id
LEFT JOIN cmr_panaudojimas
ON cmr_panaudojimas.cmr_id = cmr_kroviniai.cmr_id
AND keliones_lapas.reiso_nr = cmr_panaudojimas.reiso_nr
LEFT JOIN kroviniu_tipai
ON kroviniu_tipai.id = kroviniai.krovinio_pavadinimas
LEFT JOIN klientai
ON klientai.id = uzsakymas.kliento_id
LEFT JOIN valiutos
ON valiutos.id = uzsakymas.frachtas_valiuta
WHERE 1 = 1
AND ( `uzdaviniai`.`pasikrovimo_data` BETWEEN
'2019-07-08' AND '2019-07-08 23:59:59'
)
ORDER BY uzdaviniai.pasikrovimo_data DESC
LIMIT 300
As you can see there is many left join, statements.
4. Result
What i want is some help what can i do with this piece of crap or some recommendation what can i change. As i expect these query will take more and more time to execute.
If the query is fast when executed directly in mysql console, then the query has no problem at all, and what is slow is the php code that uses the results of the query, php code that you don't show and that you should revise/post here.
If the query is slow even in mysql console, then the problem can be the size of the master/joined tables (but this may be resolved by relaxing the memory limits of the mysql server and/or adding ram to the server), or could be non correct indexing of the joined tables, since any LEFT JOIN needs the joined table to be indexed on the field you use to join it (and this could be resolved by creating the correct indexes on the joined tables).
Consider changing your
WHERE 1 = 1
AND ( `uzdaviniai`.`pasikrovimo_data` BETWEEN
'2019-07-08' AND '2019-07-08 23:59:59'
)
TO
WHERE uzdaviniai.pasikrovimo_data BETWEEN
'2019-07-08' AND '2019-07-08 23:59:59'
and let us know results (with the backticks), please.
This query was supposed to return me four rows: which are four people with status 50 (which, in the application means "maternity leave"). But it returns only one.
On HeidiSQL the query doesn't even run because it displays a
syntax error on line 13:
(...)
corresponds to your MariaDB server version for the right syntax to use near 'a.id_regiao = '$id_regiao'
AND a.cod_status = 50
AND a.status' at line 13 */"
Here is the query. I'm slowly becoming familiar with sql statements and i did search a lot on SO before asking it:
//SELECTING PROJECT DATA
$query = "SELECT b.id_clt,b.nome AS nome_clt,
a.id_evento AS a_id_evento,a.data AS a_data,a.data_retorno AS a_data_retorno,
c.id_evento AS c_id_evento,c.data AS c_data,c.data_retorno AS c_data_retorno,
(SELECT nome FROM projeto WHERE id_projeto = a.id_projeto) AS nome_projeto,
(SELECT nome FROM curso WHERE id_curso = b.id_curso) AS nome_curso,
DATE_FORMAT(a.data,'%d/%m/%Y') AS a_data_br,
DATE_FORMAT(a.data_retorno,'%d/%m/%Y') AS a_data_retorno_br,
DATE_FORMAT(c.data,'%d/%m/%Y') AS c_data_br,
DATE_FORMAT(c.data_retorno,'%d/%m/%Y') AS c_data_retorno_br
FROM rh_eventos AS a
INNER JOIN rh_clt AS b ON (a.id_clt = b.id_clt AND a.cod_status = 50)
LEFT JOIN rh_eventos AS c ON (b.id_clt = c.id_clt AND c.cod_status = 54)
WHERE $cond_projeto a.id_regiao = '$id_regiao'
AND a.cod_status = 50
AND a.status = 1
AND NOW() BETWEEN a.data AND a.data_retorno
ORDER BY nome_projeto,b.nome;";
The problem is here in the query:
WHERE $cond_projeto a.id_regiao = '$id_regiao'
This inserts a variable (or maybe a full test?) without proper syntax. If it is a variable, include the table's column name in the criterium. If it is a full test, include AND like so:
WHERE $cond_projeto AND a.id_regiao = '$id_regiao'
Beware though! Use prepared statements, your code now appears to be vulnerable to SQL injection attacks (and those are not to be trifled with).
Here is the query, (as seen by using an echo before it) . I can see the output on heidsql now. Now its better for us to check it:
SELECT b.id_clt,b.nome AS nome_clt,
a.id_evento AS a_id_evento,a.data AS a_data,a.data_retorno AS a_data_retorno,
c.id_evento AS c_id_evento,c.data AS c_data,c.data_retorno AS c_data_retorno,
(SELECT nome FROM projeto WHERE id_projeto = a.id_projeto) AS nome_projeto,
(SELECT nome FROM curso WHERE id_curso = b.id_curso) AS nome_curso,
DATE_FORMAT(a.data,'%d/%m/%Y') AS a_data_br,
DATE_FORMAT(a.data_retorno,'%d/%m/%Y') AS a_data_retorno_br,
DATE_FORMAT(c.data,'%d/%m/%Y') AS c_data_br,
DATE_FORMAT(c.data_retorno,'%d/%m/%Y') AS c_data_retorno_br
FROM rh_eventos AS a
INNER JOIN rh_clt AS b ON (a.id_clt = b.id_clt AND a.cod_status = 50)
LEFT JOIN rh_eventos AS c ON (b.id_clt = c.id_clt AND c.cod_status = 54)
WHERE a.id_regiao = '1' AND a.cod_status = 50
AND a.status = 1
AND NOW() BETWEEN a.data AND a.data_retorno ORDER BY nome_projeto,b.nome;
I can now see the output on heidsql, though i still cant figure out why it doesent bring the other thre rows.
I'm working on my website and I'm stuck on writing MySQL query which uses "LEFT JOIN" syntax. A simple example of my query is shown bellow:
SELECT p.surname, f.f_path as players_image
FROM player p LEFT JOIN file f ON p.id_image = f.id_file
The problem is that I'm actually using 8 different tables to get necessary data and I'm joining them after WHERE clause(I found it more easier to do that way):
SELECT p.surname, f.f_path as players_image
FROM player, file
WHERE p.id_image = f.id_file
Can I somehow modify the second queries WHERE clause to get the same result as the first query returns?
I know that Oracle DB uses syntax like WHERE p.id_image(+) = f.id_file to manage that. It tried that on MySQL data base but it gave me an error.
The original SQL query(table names are different):
SELECT sp.id_speletajs, sp.vards, sp.uzvards, ss.numurs, f.f_path as attels, k.id_komanda, p.nosaukums as pozicija
FROM speletajs sp, fails f, speletaja_statistika ss, cempionata_komanda ck, komanda k, cempionats c, sezona s, pozicija p
WHERE
sp.id_attels = f.id_fails
and sp.id_speletajs = ss.id_speletajs
and ss.id_cempionata_komanda = ck.id_cempionata_komanda
and ss.id_pozicija = p.id_pozicija
and ck.id_komanda = k.id_komanda
and ck.id_cempionats = c.id_cempionats
and c.id_sezona = s.id_sezona
and k.mana_komanda = true
and s.nosaukums = (select max(s1.nosaukums) from sezona s1)
I'm running the following query using PHP's db2_prepare and db2_execute (schema names have been changed to protect the innocent):
WITH U AS (
SELECT *
FROM FOO.USR
WHERE USR_ID = ?
), UC AS (
SELECT UC.*
FROM FOO.USR_CNTRCT UC
JOIN U ON U.USR_ID = UC.USR_ID
) , LC AS (
SELECT DISTINCT CNTRCT_ID
FROM FOO.CNTRCT_LOC CL
JOIN FOO.USR_LOC UL ON UL.SLS_CTR_CD = CL.SLS_CTR_CD
JOIN U ON U.USR_ID = UL.USR_ID
WHERE CL.SLS_CTR_CD IN (?,?,?,?)
)
SELECT C.*, COALESCE(P.PGM_NM, CAST('' AS CHAR(80) CCSID 37)) AS PGM_NM,
COALESCE(ADT.ACTN_TM, TIMESTAMP('2000001', '00.00.00')) AS TIME_ORDER
FROM U, FOO.CNTRCT AS C
LEFT JOIN FOO.CNTRCT_PGM CP ON CP.CNTRCT_ID = C.CNTRCT_ID
LEFT JOIN FOO.PGM P ON P.PGM_ID = CP.PGM_ID
LEFT JOIN UC ON UC.CNTRCT_ID = C.CNTRCT_ID
LEFT JOIN (
SELECT ENTY_ID AS CNTRCT_ID, MAX(ACTN_TM) AS ACTN_TM
FROM FOO.ADT A JOIN U ON U.USR_ID = A.USR_ID
WHERE ENTY_TP = 'CT'
GROUP BY ENTY_ID
) AS ADT ON ADT.CNTRCT_ID = C.CNTRCT_ID
WHERE C.APP = ?
AND (
((SELECT COUNT(*) FROM UC) > 0 AND UC.CNTRCT_ID IS NOT NULL)
OR
((SELECT COUNT(*) FROM UC) = 0 AND UC.CNTRCT_ID IS NULL)
)
AND ? BETWEEN YEAR(STRT_DT) AND YEAR(END_DT)
AND (LOWER(CNTRCT_NM) LIKE ?)
ORDER BY CNTRCT_NM ASC
I've confirmed that my parameters are correct in number and in order. When I execute this query, php returns two errors: Describe Param Failed and Binding Error.
I've narrowed the problem down to this line: CL.SLS_CTR_CD IN (?,?,?,?). If I use actual values here instead of parameters, the query runs fine.
The environment is Zend Server for IBM i, PHP 5.3, DB2 (on i) V6R1. The only help I get from the job log (QEZJOBLOG) is an SQL0313 (Number of host variables not valid).
Again, I've confirmed that I'm providing the correct number of variables. The Describe Param Failed error makes me wonder if PHP is struggling to determine the type of those four parameters. They should be type string(2), and a var_dump of the parameter array passed to db2_execute confirms that they have been cast as such.
I'm going to switch to using the values instead of parameters for that specific line, but it's going to drive me crazy until I figure out what's going on.
Thanks
Chad
I had a few issues with db2_prepare and db2_execute whith bind params in complex queries with this PTFs level:
SF99601 15 DB2 FOR IBM i
SF99354 8 TCP/IP GROUP PTF
SF99115 14 IBM HTTP SERVER FOR i
Upgrading to levels
20 DB2
11 TCP/IP
20 IBM HTTP
the issues disappear and I was return to a permisive crazy level :)
I am trying to perform a query in a PHP script. The query works fine in my MySQL client however it does not seem to working within my code. I am using PDO. I am thinking it might have limitations, because it seems to work fine with a less complicated query.
Here is the query:
SELECT D.status, D.createdBy, D.createDate, D.modifiedBy, D.modifiedDate,D.IPAddress, D.adminStatus, D.campus, D.buildingID, D.deviceShortName, D.distributionID, D.networkKey, D.deviceName, D.test, D.pkDevices, D.DNSRule, D.Domain, D.DNSOverride, D.noDNS, D.pkModel, DM.Model, DM.pkManufacturer, M.manufacturer FROM Devices AS D INNER JOIN DeviceModel AS DM ON D.pkModel = DM.pkModel INNER JOIN Manufacturer AS M ON DM.pkManufacturer = M.pkManufacturer WHERE D.status = '1' AND D.adminStatus = 'Active' ORDER BY D.deviceName
Here is where I am trying to call it in my script:
$dbhDevices = newPDO('mysql:host='.$_SESSION['OpsDBServer'].'.ops.tns.its.psu.edu;dbname='.$_SESSION['OpsDB'], $_SESSION['yoM'], $_SESSION['aMa']);
$sqlDevices = "SELECT D.status, D.createdBy, D.createDate, D.modifiedBy,
D.modifiedDate, D.IPAddress, D.adminStatus, D.campus, D.buildingID,
D.deviceShortName, D.distributionID, D.networkKey, D.deviceName, D.test,
D.pkDevices, D.DNSRule, D.Domain, D.DNSOverride, D.noDNS, D.pkModel, DM.Model,
DM.pkManufacturer, M.manufacturer
FROM Devices AS D
INNER JOIN DeviceModel AS DM ON D.pkModel = DM.pkModel
INNER JOIN Manufacturer AS M ON DM.pkManufacturer = M.pkManufacturer
WHERE D.status = '1' AND D.adminStatus = 'Active' ORDER BY D.deviceName";
foreach ($dbhDevices->query($sqlDevices) as $rowDevices)
{
Again, the query does work with the MySQL client.
try enabling errors if haven't done already:
error_reporting(E_ALL);
$dbhDevices->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
In the older versions of PDO usage you have to "initialize" your PDO variable when you declare it for some reason. Try putting a line before this code that generically initializes $dbhDevices and see if that does the trick. I have my doubts because you say it works fine with less complicated queries but it's worth a try.
I got it working by using a LEFT JOIN instead of an INNER JOIN. Strange, but it is working.