tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

DIBI nebere slozitejsi vyraz, hlasi jako chybu

před 10 lety

Kcko
Člen | 292

Ahoj,

potrebuji poradit s timto problemem.

<?php
SELECT ROUND(( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(datum_narozeni)) /  (86400 * 365), 1)
?>

Tento SQL dotaz je v poradku. A pokud aplikuji slucovaci funkci CONCAT

<?php
SELECT  CONCAT(ROUND(( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(datum_narozeni)) /  (86400 * 365), 1), ' test ')
?>

Tak DIBI zahlasi Fatal error: Uncaught exception ‚DibiException‘ with message 'SQL translate error: SELECT SQL_CALC_FOUND_ROWS CONCAT(ROUND / (86400 * 365), 1), Alone quotetest

V phpMyadminu se dotaz normalne provede. Pokousel jsem se i zaclenit modifikator %sql ale to same.

Muze me nekdo prosim nasmerovat?

Cela metoda vypada takto ( i kdyz to nebude dulezite )

<?php
    protected function getStatsPlayersData2($type)
    {
        $where = "";

        /*                                  'nejstarsi-hraci'   => 'Nejstarší hráči',
                                            'nejmladsi-hraci'   => 'Nejmladší hráči',
                                            'nejvyssi-hraci'    => 'Nejvyšší hráči',
                                            'nejnizsi-hraci'    => 'Nejnižší hráči',
                                            'nejtezsi-hraci'    => 'Nejtěžší hráči',
                                            'nejlehci-hraci'    => 'Nejlehčí hráči',*/

        switch ($type)
        {
            case 'nejstarsi-hraci':
            $where = "datum_narozeni";
            //$value = "UNIX_TIMESTAMP(datum_narozeni) ";
            $value = "ROUND(( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(datum_narozeni)) /  (86400 * 365), 1) ";
            //$age = number_format((time() - $unix) / (86400 * 365), 1);
            //$value = "UNIX_TIMESTAMP(datum_narozeni)";
            $value2 = "datum_narozeni, ";
            $sort  = "ASC";
            break;

            case 'nejmladsi-hraci':
            $where = "datum_narozeni";
            $value = "CONCAT(ROUND(( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(datum_narozeni)) /  (86400 * 365), 1), 'test') "; // tady je takova jako chybka, u poradi ve vypisu pak nebude presne odpovidat, protoze to zaokrouhluji
            $value2 = "datum_narozeni, ";
            $sort  = "DESC";
            break;

            case 'nejvyssi-hraci':
            $where = "vyska";
            $value = "vyska";
            $sort  = "DESC";
            break;

            case 'nejnizsi-hraci':
            $where = "vyska";
            $value = "vyska";
            $sort  = "ASC";
            break;

            case 'nejtezsi-hraci':
            $where = "vaha";
            $value = "vaha";
            $sort  = "DESC";
            break;

            case 'nejlehci-hraci':
            $where = "vaha";
            $value = "vaha";
            $sort  = "ASC";
            break;

            // exit
            default:
                return;
        }

        $this->str = new Strankovani(COMPET_STATS_LIMIT, "l");
        $q = "  SELECT
                SQL_CALC_FOUND_ROWS
                ".$value." as _count,
                ".$value2."
                t2.jmeno as hrac_nazev,
                t2.alternativni_jmeno,
                t3.nazev as soutez_nazev,
                t4.nazev as sezona_nazev,
                t3.seo as soutez_seo,
                t4.seo as sezona_seo,
                t5.nazev as tym_nazev,
                t5.seo as tym_seo,
                n.ID as  zeme_id,
                n.nazev as narodnost_nazev,
                n.zkratka as narodnost_zkratka,
                t1.hracID as hrac_id,
                t1.tymID
                FROM
                soupisky t1
                JOIN rejstrik_hraci t2 ON t2.ID = t1.hracID
                JOIN souteze t3 ON t3.ID = t1.soutezID
                JOIN sezony t4 ON t4.ID = t1.sezonaID
                JOIN rejstrik_tymy t5 ON t5.ID = t1.tymID
                JOIN narodnosti n ON n.ID = t2.narodnost
                WHERE
                soutezID = %i
                AND sezonaID = %i
                ORDER BY ".$where." ".$sort.",  hrac_nazev, hrac_id ASC
                LIMIT ".$this->str->l.", ".$this->str->rows
                ;


        $rows = DIBI::fetchAll($q, Compet::$selected_compet['ID'], Compet::$selected_season['ID']);
        $this->str->pocet_radku = $this->str->PocetRadku();
        DIBI::dump();

        return $rows;
    }
?>

Vypisovana chybka

<?php


Fatal error: Uncaught exception 'DibiDriverException' with message 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'test, '%Y-%m-%d')'

?>

Ja nevim :/

Editoval Kcko (22. 10. 2009 17:04)

před 10 lety

LastHunter
Člen | 1539

Místo fetchAll zavolej test, uvidíš, jak dibi tu query složí.

před 10 lety

Kcko
Člen | 292

LastHunter napsal(a):

Místo fetchAll zavolej test, uvidíš, jak dibi tu query složí.

Slozite se tak jak ma a tak jak to pote funguje v PMA.
Tj takto …

<?php
SELECT
 SQL_CALC_FOUND_ROWS
 CONCAT(ROUND(( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(datum_narozeni)) / (86400 * 365), 1), 'test') as
_count,
.
.
.

?>

Ale DIBI rve …

<?php

Fatal error: Uncaught exception 'DibiDriverException' with message 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'test, '%Y-%m-%d')' at line 6' in C:\wamp\www\private\w-e-b-s\2009\Pesonline-svn-new\library\DIBI\dibi\drivers\mysql.php:

?>

Zajimava je dalsi vec. Kdyz sloupec spojim se slovem test (ciste pro ukazku) a dam ho dopredu tudiz

<?php

$value = "CONCAT('test', ROUND(( UNIX_TIMESTAMP() - UNIX_TIMESTAMP(datum_narozeni)) /  (86400 * 365), 1)) ";
?>

Tak dotaz opet funguje v PMA a dostavam hodnoty slozene ze slova „test“+vek ale DIBI zarve

<?php
Fatal error: Uncaught exception 'DibiDriverException' with message 'Unknown column 'test39.3' in 'where clause'' in C:\wamp\www\private\w-e-b-s\2009\Pesonline-svn-new\library\DIBI\dibi\drivers\mysql.php:167
?>

Budu muset prozkoumat driver mysql.php co se tam vubec deje, ale preci jen , nevi nekdo , neprijde mi to moc jako standardni chovani.

PS. Pokud pouziji klasicke mysql_query a mysql_fetch_array tak to FUNGUJE ( stejne jako v PMA )
Takze co s DIBI? :-)

Editoval Kcko (22. 10. 2009 19:43)

před 10 lety

LastHunter
Člen | 1539

Rikam ti, misto dibi::fetchAll zavolej dibi::test, ta query se ti vypise ta obrazovku a uvidis, kde to dibi spatne preklada.

před 10 lety

Kcko
Člen | 292

LastHunter napsal(a):

Rikam ti, misto dibi::fetchAll zavolej dibi::test, ta query se ti vypise ta obrazovku a uvidis, kde to dibi spatne preklada.

Samozrejme ze ano.

<?php
    $rows = DIBI::test($q, Compet::$selected_compet['ID'], Compet::$selected_season['ID']);
?>

A vystup jsem pokladal uz vyse.

před 10 lety

phx
Člen | 652

Tak nam jeste ukaz obsah promeny $q.

před 9 lety

had12
Člen | 28

ahoj, já jsem narazil na stejný problém.
mám sql dotaz:

SET @moje_id='.$id.';
  SELECT mensenec.*
  FROM
    (SELECT DISTINCT :prefix:osoby.*
     FROM (:prefix:osoby
        JOIN :prefix:osoby_spolecenstvi ON :prefix:osoby.id=:prefix:osoby_spolecenstvi.id_osoba)
        JOIN
          (SELECT DISTINCT :prefix:osoby.id AS ja_id,
              :prefix:osoby_spolecenstvi.id_spolecenstvi AS ja_spolecenstvi
           FROM :prefix:osoby
              JOIN :prefix:osoby_spolecenstvi ON :prefix:osoby.id=:prefix:osoby_spolecenstvi.id_osoba
           WHERE :prefix:osoby.id=@moje_id) AS ja ON :prefix:osoby_spolecenstvi.id_spolecenstvi=ja.ja_spolecenstvi
     WHERE :prefix:osoby.id!=ja.ja_id) AS mensenec
  LEFT JOIN
    (SELECT DISTINCT :prefix:osoby.*
     FROM (:prefix:osoby
        JOIN :prefix:osoby_vztahy ON (:prefix:osoby.id=:prefix:osoby_vztahy.id_osoba1 OR :prefix:osoby.id=:prefix:osoby_vztahy.id_osoba2))
        JOIN
          (SELECT DISTINCT :prefix:osoby.id AS ja_id
           FROM :prefix:osoby
           WHERE :prefix:osoby.id=@moje_id) AS ja ON IF(:prefix:osoby_vztahy.id_osoba1=:prefix:osoby.id, :prefix:osoby_vztahy.id_osoba2, :prefix:osoby_vztahy.id_osoba1)=ja.ja_id
     WHERE :prefix:osoby.id!=ja.ja_id) AS mensitel USING(id)
  WHERE mensitel.id IS NULL;

a když pustím dibi::test, tak se mi vypíše sql dotaz, ten po zkopírování do phpmyadmina funguje správně, ovšem když nechám dibi::query, tak skončí chybou:

Fatal error: Uncaught exception ‚DibiDriverException‘ with message ‚You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT mensenec.* FROM (SELECT DISTINCT osoby.* FROM (osoby ' at line 2‘ in C:\server\apache\htdocs\vztahy\dibi\dibi.php:1047 Stack trace: #0 C:\server\apache\htdocs\vztahy\dibi\dibi.php(231): DibiMySqlDriver->query('SET @moje_id=1;...') #1 C:\server\apache\htdocs\vztahy\dibi\dibi.php(212): DibiConnection->nativeQuery('SET @moje_id=1;...') #2 C:\server\apache\htdocs\vztahy\dibi\dibi.php(897): DibiConnection->query(Array) #3 C:\server\apache\htdocs\vztahy\profil.php(121): dibi::query('SET @moje_id=1;...') #4 {main} SQL: SET @moje_id=1; SELECT mensenec.* FROM (SELECT DISTINCT osoby.* FROM (osoby JOIN osoby_spolecenstvi ON osoby.id=osoby_spolecenstvi.id_osoba) JOIN (SELECT DISTINCT osoby.id AS ja_id, osoby_spolecenstvi.id_spolecenstvi AS ja_spol in C:\server\apache\htdocs\vztahy\dibi\dibi.php on line 1047

tak čím to, prosím, může být?? $id obsahuje nějaké ID osoby, třeba 1 nebo 2…

před 9 lety

Ondřej Mirtes
Člen | 1539

Já si myslím, že nemůžeš do databáze narvat v jednom dibi::query dva dotazy oddělené středníkem, místo toho syntax erroru by tomu odpovídalo. Zavolej jedno dibi::query s nastavením té proměnné a druhé dibi::query s tím velkým SELECTem.

BTW – jak tam rveš tu $id proměnnou z PHP, tak obcházíš celé dibi a vystavuješ to náchylnosti na SQL injection. Projdi si quick start.