tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

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

Problemy Dibi s MS SQL – LIMIT

před 7 lety

KingKoca
Člen | 25

Ahoj, pouzivam aktualni Dibi, php 5.3 a SQL server 2008. Pri vyvoji aplikace jsem narazil na problemy s LIMITem:

  1. pri pouziti metod napr. fetchSingle nebo pri pouziti LIMIT $query->limit(3); je vygenerovany dotaz spatny:

SELECT TOP 1 * FROM (SELECT [sort] AS [t] FROM [pages])

SQL hlasi chybu: Incorrect syntax near ')'. MS SQL vyzaduje, aby byl vnoreny dotaz pojmenovany, napr:

SELECT TOP 1 * FROM (SELECT [sort] AS [t] FROM [pages]) AS [subquery]

Pak uz to je v poradku. V mssql driveru to neni tezka oprava, prosim jen aby to tam nekdo vlozil.

2. Druhy problem uz je zapeklitejsi. Vypada to, ze vnorene dotazy se neprekladaji tak jak by mely. Pri pouziti kodu:

<?php
$query = $this->db->select('*')
    ->from($this->table)->as('t');
$query->limit(1);
$innerQuery = $query;
$query = $this->db->select('*')->from($innerQuery)->as('t');
?>

Muze vygenerovat dotaz:

SELECT *
FROM (
SELECT *
FROM [ctech_pages] AS [t]
LIMIT 1) AS [t]
WHERE ([parent] = 0) AND (tl.status > 0) AND ([homepage] = 1)
ORDER BY [sort]

Vsimnete si toho LIMITu. DibiTranslator to ocividne neposila do driveru, jinak by tam LIMIT nikdy nedal.

Znamena to tedy, ze pokud mam MS SQL, tak musim svoje sql dotazy, ikdyz psane pres DibiFluent, psat na miru pouzite databazi?

Diky za jakoukoliv odpoved.

před 7 lety

Milo
Nette Core | 1119

Jaký driver používáš?

Zkus si do DibiFluent cvičně přidat:

public function limit($limit)
{
    $this->cursor[] = '%lmt';
    $this->cursor[] = $limit;
    return $this;
}

před 6 lety

xxxmisko
Člen | 140

Ahoj!

Mám podobný problém ako kolega nado mnou. Nainštaloval som do php ovládače od MS, pričom do db sa pripájam cez pdo_sqlsrv.

Problém je, že dibi mi hlási pri funkcii fetch() takúto chybku:

DibiNotSupportedException

PDO or driver does not support applying limit or offset.

je to riadok 383 v pdo.php.

Vedeli by ste mi niekto pomôcť, ako rozchodiť mssql 2008 + dibi + poprípade nette? (využívam nette)

Ďakujem za každú pomoc

před 6 lety

Milo
Nette Core | 1119

Nedávno jsem poslal Pull Request pro přidání sqlsrv driveru pro Nette\Database. Pokud používáš Nette dev verzi, můžeš si zkusit začlenit ten první commit Database: added supplemental SqlsrvDriver.

Pokud jde o Dibi, a nepotřebuješ nutně PDO, zkus driver MsSql2005.

před 6 lety

xxxmisko
Člen | 140

Milo, som z toho trošku jeleň, keď mám pravdu povedať.

používam:
Nette 2.0.10
Dibi 2.0.2

Je mi jedno, či budem PDO používať, alebo nie. Ja som jednoducho som postupoval podľa návodov, ale žiaľ výsledok sa mi nepodarilo rozbehať :(
Skrátka potrebujem, aby mi namiesto terajšieho postgresu začala v určitom okamihu šlapať mssql.

Prosím ak máš pre mňa najjednoduchšie možné riešenie, prosím ťa o neho, lebo už ma to prestáva baviť, že som taký bezmocný :D

před 6 lety

Milo
Nette Core | 1119

Více info na Nette fóru.

před 6 lety

xxxmisko
Člen | 140

no už som znova tu :D

Počuj, čo sme pridávali riadok do pdo.php:

case 'sqlsrv':

s týmto mi nefungovali korektne dotazy:

$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';

Generovalo

SELECT TOP 10 * FROM (SELECT [cislo_uctu], ['zostatok'] FROM [narodna_banka] WHERE [zostatok] > 9999 ORDER BY [zostatok] ASC) t

Pričom MSSQL má problém s klauzulou ORDER BY vo vnorenom SELECTE. Upravil som to nie pekne, ale ide to:

$sql = str_ireplace('SELECT', 'SELECT TOP '. (int) $limit .' ', $sql);

Teraz to vygeneruje:

SELECT TOP 10 [cislo_uctu], [zostatok] FROM [narodna_banka] WHERE [zostatok] > 9999 ORDER BY [zostatok] ASC

čo je správny dotaz.

Môžem to tam nechať, alebo je to na prd? Nezistil som, kde sa spúšta tá funkcia applyLimit

Editoval xxxmisko (11. 4. 2013 16:20)

před 6 lety

Milo
Nette Core | 1119

Jestli nepoužíváš vnořené selecty, tak to tam klidně nech. Musím to nejprve vyzkoušet, otevřu pak issue na Githubu.

před 6 lety

xxxmisko
Člen | 140

vnorené selecty nebudem používať, maximálne nejaké joiny atď. DB model je celkom fajn navrhnutý :D

před 6 lety

xxxmisko
Člen | 140

toto riešenie bude kapánek lepšie:

$sql = preg_replace('/SELECT/', 'SELECT TOP '. (int) $limit .' ', $sql, 1);