Database Explorer->Select změní vkládaný string doplní ho o apostrofy

OdpadlikCZ
Člen | 11
+
0
-

Prosím o radu co dělám špatně.
Když mám přes Database Explorer (nette/database v3.1.1) složený dotaz:

$search = $this->database
			->table($this->tblPopis)
			->select('*, ROUND ( ( LENGTH(text)- LENGTH( REPLACE ( text, "'.$text.'", "") )    ) / LENGTH("'.$text.'")   ) AS count ');
			->where('text LIKE ?' , '%'.$text.'%' )
			->order('count DESC');

a do proměnné $text dám string „návod k použití“ TRACY ukáže, že se volá dotaz:
(značky ` nahrazeny ‚, protože to jinak vzalo jako formátování tématu typu 'code‘)

SELECT *, ROUND ( ( LENGTH('text')- LENGTH(
REPLACE ( 'text', "ná'vod' 'k' 'pou'ž'it'í", "") ) ) / LENGTH("ná'vod' 'k' 'pou'ž'it'í") ) AS
'count'
FROM 'popis'
WHERE ('text' LIKE '%návod k použití%')
ORDER BY 'count' DESC

SELECT *, ROUND ( ( LENGTH(‚text‘)- LENGTH(
REPLACE ( ‚text‘, „ná'vod' ‚k‘ ‚pou'ž'it'í“, "") ) ) / LENGTH(„ná'vod‘ ‚k‘ ‚pou'ž'it'í“) ) AS
'count‘
FROM ‚popis‘
WHERE (‚text‘ LIKE ‚%návod k použití%‘)
ORDER BY ‚count‘ DESC

a ‚count‘ je všude 0.

Pokud ovšem to samé udělám přes Database Core

$sql = 'SELECT *, ROUND ( ( LENGTH(text)- LENGTH( REPLACE ( text, "'.$text.'", "") )    ) / LENGTH("'.$text.'")   ) AS count '.
       'FROM '.$this->tblPopis.
$sql .= "WHERE text LIKE '%".$text."%'";
$sql .= ' ORDER BY count DESC';
$search = $this->database->fetchAll($sql);

TRACY ukáže, že se volá dotaz

SELECT *, ROUND ( ( LENGTH(text)- LENGTH(
REPLACE ( text, "návod k použití", "") ) ) / LENGTH("návod k použití") ) AS count
FROM popis
WHERE text LIKE '%návod k použití%'
ORDER BY 'count' DESC

A proměná count má už nějaké hodnoty.

Zajímavé je, že v Database Explorer v Select to ten string przní vždy jinak.

hledat na tv = hledat ‚na‘ tv
k pluhu = k pluhu
k rámu = k 'r'ámu

Víte někdo jak to obejít, aby se tam vložil správný řetězec a nebo poradit jak to udělat jinak. Předem moc dík.

Editoval OdpadlikCZ (31. 8. 2021 10:26)

David Matějka
Moderator | 6445
+
+3
-

Ahoj,
Vždy používej parametry (ten otazník, stejně jako to děláš u where)

OdpadlikCZ
Člen | 11
+
0
-

Díky, za radu. To jsem zkoušel, ale zkolabuje to.

File: ...\src\Database\SqlPreprocessor.php:119
throw new Nette\InvalidArgumentException('There are more parameters than placeholders.');

Call stack
Nette\InvalidArgumentException
There are more parameters than placeholders

SQL příkaz se vůbec neprovede, jako by ->select neuměl nahradit otazníky za proměnné.

Editoval OdpadlikCZ (31. 8. 2021 10:21)

Marek Bartoš
Nette Blogger | 1146
+
0
-

Prosím tě, používej zvýraznění kódu, takhle se tvůj příspěvěk hrozně špatně čte. Jde o ikonku „php“ nad editorem. Stejně jdou zvýraznit i jiné jazyky, jen přepíšeš název jazyka.

Chyba vypadá vcelku jasně, předal jsi více proměnných, než otazníků (placeholderů). Pro každý otazník je třeba předat jednu proměnnou.

OdpadlikCZ
Člen | 11
+
0
-

Omlouvám se, napravím se :) upravil jsem

Použil jsem následující úpravu v ->select()

$search = $this->database->table($this->tblPopis)
                ->select('*, ROUND ( ( LENGTH(text)- LENGTH( REPLACE ( text, "?", "") )    ) / LENGTH("?")   ) AS count ', $text, $text);

a ta hodí tu chybu

File: ...\src\Database\SqlPreprocessor.php:119
throw new Nette\InvalidArgumentException('There are more parameters than placeholders.');

Call stack
Nette\InvalidArgumentException
There are more parameters than placeholders

Editoval OdpadlikCZ (31. 8. 2021 11:07)

OdpadlikCZ
Člen | 11
+
0
-

Když dám jen jeden parametr

$search = $this->database->table($this->tblPopis)
          ->select('*, ROUND ( ( LENGTH(text)- LENGTH( REPLACE ( text, "?", "") )    ) / LENGTH("?")   ) AS count ', $text);

Tak je to špatně, ale projde to a samozřejmě zařve SQL ERROR

Nette\Database\DriverException #42000
SQLSTATE[42000]: Syntax error or access violation: 1064 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 '%návod k použití%' at line 1 search►

SQL >

SELECT *, ROUND ( ( LENGTH(`text`)- LENGTH(
REPLACE ( `text`, "'návod k použití'", "") ) ) / LENGTH("?") ) AS `count`
FROM `popis`
WHERE (`text` LIKE ?)
ORDER BY `count` DESC %návod k použití%


OdpadlikCZ
Člen | 11
+
0
-

Zkoušel jsem různé experimenty, jako třeba dát u toho ->select() ty parametry jako array, Tak se v selectu oba parametry nahradí, ale zase to přestane fungovat u podmínky WHERE :(

$search = $this->database->table($this->tblPopis)
          ->select('*, ROUND ( ( LENGTH(text)- LENGTH( REPLACE ( text, "?", "") )    ) / LENGTH("?")   ) AS count ', [$text, $text])
		  ->where('text LIKE ?' , $text )
		  ->order('count DESC');

Hodí to SQL ERRROR



Nette\Database\DriverException #42000
SQLSTATE[42000]: Syntax error or access violation: 1064 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 'návod k použití' at line 1 search►
Caused by PDOException

SELECT *, ROUND ( ( LENGTH(`text`)- LENGTH(
REPLACE ( `text`, "'návod k použití'", "") ) ) / LENGTH("'návod k použití'") ) AS `count`
FROM `popis`
WHERE (`text` LIKE ?, ?)
ORDER BY `count` DESC návod k použití

Tuší někdo co s tím, díky?

OdpadlikCZ
Člen | 11
+
0
-

Problém vyřešen. Vadí mu, že otazníky jsou v uvozovkách „?“.
Pokud použiji

$search = $this->database
			->table($this->tblPopis)
			->select('*, ROUND ( ( LENGTH(text)- LENGTH( REPLACE ( text, ? , "") )    ) / LENGTH( ? )   ) AS count ', $text, $text);
            ->where('text LIKE ?' , '%'.$text.'%' )
			->order('count DESC');

Vše již běží.