tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

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

Modifikátor %s se nenahrazuje hodnotou

před 8 lety

al1716
Člen | 6

Zdravím,
zkoušel jsem sestavit dotaz pomocí

dibi::test('SELECT * FROM `table` WHERE %and', array(
    array('vek = %i', 10),
    array('vyska = %i', 100),
));

SELECT *
FROM `table`
WHERE (vek = 10) AND (vyska = 100)

To je v pořádku, ale pokud modifikátor %i nahradím modifikátorem %s, dostanu na dotaz

dibi::test('SELECT * FROM `table` WHERE %and', array(
    array('vek = %s', '10'),
    array('vyska = %s', '100'),
));

SELECT *
FROM `table`
WHERE (vek = '') AND (vyska = '')

Dělam něco špatně? Stejně to „blbne“ i při použití tekutých příkazů.
Díky za nějakou radu, nebo nasměrování.

Apache/2.2.19 (Win32) PHP/5.3.8
dibi: 1.5-rc1

Editoval al1716 (21. 9. 2011 12:45)

před 8 lety

HosipLan
Moderator | 4693

Zkus to takto:

dibi::test('SELECT * FROM `table` WHERE %and', array(
    array('vek%s' => '10', 'vyska%s' => '100'),
));

před 8 lety

al1716
Člen | 6

Díky za odpověď. Zkusil jsem tvůj příklad u druhé podmínky malinko obměnit a stejně je to nějaký divný

dibi::test('SELECT * FROM `table` WHERE %and', array(
    array('vek%s' => '10', 'vyska = %s' => '100'),
));


SELECT *
FROM `table`
WHERE (10 100)

před 8 lety

HosipLan
Moderator | 4693

Promiň, malinko špatně… :)

dibi::test('SELECT * FROM `table` WHERE %and', array(
    'vek%s' => '10',
    'vyska%s' => '100'
));

Měl jsem tam dvě pole v sobě.

před 8 lety

al1716
Člen | 6

Zkusil jsem to a výsledek je stejný jako v prvním příspěvku tedy

dibi::test('SELECT * FROM `table` WHERE %and', array(
        'vek%s' => '10',
        'vyska%s' => '100'
));

SELECT *
FROM `table`
WHERE (`vek` = '') AND (`vyska` = '')

Nejvíc mě zaráží, že když tam %s vyměním za %i, tak to ten dotaz poskládá správně (napadlo mě, jestli to není verzí, ale zkoušel jsem latest i 1.2 a chová se to stejně) :/

Editoval al1716 (21. 9. 2011 15:27)

před 8 lety

HosipLan
Moderator | 4693

Tohle prostě musí fungovat.. jestli ne, tak si stáhni dibi z githubu

dibi::test('SELECT * FROM `table` WHERE %and', array(
        'vek' => '10',
        'vyska' => '100'
));

před 8 lety

al1716
Člen | 6

Tvůj poslední příklad

dibi::test('SELECT * FROM `table` WHERE %and', array(
        'vek' => '10',
        'vyska' => '100'
));

SELECT *
FROM `table`
WHERE (`vek` = '') AND (`vyska` = '')

Stáhl jsem si klon dibi z githubu a stále to nedělá to, co bych si myslel, že to dělat má. Požadovaného dotazu jsem dosáhl pomocí

dibi::test('SELECT * FROM `table` WHERE %and', array(
        array('vek = ', '10'),
        array('vyska = ', '100')
));

SELECT *
FROM `table`
WHERE (vek = 10) AND (vyska = 100)

U příkladu s věkem a výškou ty parametry snadno ošetřím pomocí intval(), ale co kdybych chtěl kontrolovat jméno?

dibi::test('SELECT * FROM `table` WHERE %and', array(
        array('jmeno = ', "Connan"),
        array('prijmeni = ', "O'Brian")
));

prijmeni = O**Alone quote**Brian

podobně v případě, že na ta data použiju mysql_real_escape_string() nebo podobnou funkci

dibi::test('SELECT * FROM `table` WHERE %and', array(
        array('jmeno = ', "Connan"),
        array('prijmeni = ', mysql_real_escape_string("O'Brian"))
));

prijmeni = O\**Alone quote**Brian // oproti předchozímu je zde ještě zpětné lomítko

Editoval al1716 (21. 9. 2011 16:06)

před 8 lety

Milo
Nette Core | 1119

Syntaxe je OK.

Jsi připojený k databázi když to testuješ? Řetězce se v MySQL driveru escapují pomocí mysql_real_escape_string() a tahle funkce vyžaduje aktivní připojení. Jinak je totiž vráceno false a to se vyhodnotí jako prázdný řetězec. Zapnuté error_reporting(E_ALL) máš?

Editoval Milo (21. 9. 2011 16:20)

před 8 lety

al1716
Člen | 6

Jáááj! Já mám v php nastaveno error_reporting = E_ALL | E_STRICT, ale v tom skriptu bylo nastaveno error_reporting(0). Když jsem to zakomentoval, tak vyskočilo několik varování a poznámek včetně

Warning: mysql_real_escape_string(): 23 is not a valid MySQL-Link resource in ...\libs\dibi\drivers\mysql.php on line 305

Před tím mým skládáním dotazu je použita nějaká funkce, ve které se volá mysql_close();

Tímto vám oběma děkuju za nápady a HosipLan(ovi? :)) navíc za trpělivost. Díky!

před 8 lety

HosipLan
Moderator | 4693
dibi::test('SELECT * FROM `table` WHERE %and', array(
        array('vek = ', '10'),
        array('vyska = ', '100')
));

SELECT *
FROM `table`
WHERE (vek = 10) AND (vyska = 100)

Tohle je myslím bezpečností díra. Nejsem si jistý, jestli dibi správně pozná, že to druhé je parametr… Můžeš ale zkusit ještě alternativní syntaxi, kterou mám osobně mnohem raději, protože je čitelnější

dibi::select('*')->from('table')
    ->where('vek = %s', '10')
        ->and('vyska = %s', '100')
    ->test(); // vypíše SQL, s ->fetch() vykoná dotaz

Nebo pokud potřebuješ dynamicky ty podmínky

$q = dibi::select('*')->from('table');

$podminky = array('vek' => '10', 'vyska' => '100');
foreach ($podminky as $column => $value) {
    $q->where('%n = %s', $column, $value);
}
$q->test();

Ale tvůj kód je jinak správně i podle dokumentace… Divné… :-/

před 8 lety

al1716
Člen | 6

HosipLan: Znovu díky za nápady, trpělivost a i za tu alternativni syntaxi. Milo mě nakopl správným směrem. Jak už jsem psal bylo to tím, že ve funkci před skládáním dotazu byla volána funkce mysql_close().