tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

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

Použití funkce getIterator – problém

před 5 lety

s.cerny67
Člen | 4

Ahoj,
patrně dělám někde chybu, nebo jsem tuto funkci nepochopil, takže prosím o radu.
Chtěl jsem podle návodu použít tento kód:

$result = dibi::query('SELECT * FROM PRIJEMCI_TEST');

FB::log(count($result));

foreach ($result->getIterator(5, 5)
          as $n => $row) {

 FB::log($row);
    //print_r($row);

}

Používám driver pro MSSQL, ale předpokládal jsem, že ten iterátor se použije až na result to znamená na všechny záznamy, které vrátí Select.
Stále mám stejný výsledek, SELECT vrací stejný počet záznamů jako ve smyčce foreach, všechny záznamy v tabulce.

Díky.
Standa

Editoval s.cerny67 (23. 7. 2014 13:33)

před 5 lety

Milo
Nette Core | 1119

Metoda getIterator() nepřijímá žádné parametery. Jesli chceš limit/offset, můžeš použít fluent:

foreach (dibi::select('SELECT * FROM PRIJEMCI_TEST')->limit(5)->offset(10) as $row) {
    ...
}

před 5 lety

s.cerny67
Člen | 4

Milo napsal(a):

Metoda getIterator() nepřijímá žádné parametery. Jesli chceš limit/offset, můžeš použít fluent:

foreach (dibi::select('SELECT * FROM PRIJEMCI_TEST')->limit(5)->offset(10) as $row) {
  ...
}

Díky to určitě otestuju, vycházel jsem z oficiální verze na: https://dibiphp.com/cs/quick-start

Je možné také nastavit offset a eventuálně i limit

$result = dibi::query('SELECT * FROM table');

$offset = 10;
$limit = 3;

foreach ($result->getIterator($offset, $limit)
          as $n => $row) {
    print_r($row);
}

Editoval s.cerny67 (23. 7. 2014 17:21)

před 5 lety

s.cerny67
Člen | 4

Milo napsal(a):

Metoda getIterator() nepřijímá žádné parametery. Jesli chceš limit/offset, můžeš použít fluent:

foreach (dibi::select('SELECT * FROM PRIJEMCI_TEST')->limit(5)->offset(10) as $row) {
  ...
}

Dibi upraví dotaz na „SELECT SELECT * FROM PRIJEMCI_TEST LIMIT 10 OFFSET 5“.
První problém jsou dva SELECTy, ale hlavně MSSQL neumí LIMIT ani OFFSET. Takže jsem musel použít jako již dříve Stored Proceduru nahrazující tento nedostatek.

Díky

před 5 lety

Milo
Nette Core | 1119

Záleží, jakou verzi MSSQL používáš. SQL Server 2012 to jakštakš zvládá. Obecně je to ale porod. Nevyplatilo by se napsat napsat celý SQL dotaz ručně? Nevím, jak to bude kompatibilní…

dibi::query('
SELECT id, name FROM (
    SELECT
        id, name,
        ROW_NUMBER() OVER (ORDER BY id) AS __row_num
    FROM
        author AS author
) __inner WHERE __row_num BETWEEN %i AND %i', $offset + 1, $offset + $limit);

před 5 lety

s.cerny67
Člen | 4

Milo napsal(a):

Záleží, jakou verzi MSSQL používáš. SQL Server 2012 to jakštakš zvládá. Obecně je to ale porod. Nevyplatilo by se napsat napsat celý SQL dotaz ručně? Nevím, jak to bude kompatibilní…

dibi::query('
SELECT id, name FROM (
  SELECT
      id, name,
      ROW_NUMBER() OVER (ORDER BY id) AS __row_num
  FROM
      author AS author
) __inner WHERE __row_num BETWEEN %i AND %i', $offset + 1, $offset + $limit);

Je to pro verzi 2010 a tam tato konstrukce myslím ještě nefunguje.

Jen pro zajímavost tady je ta obrzlička formou Stored Procedury:
`
ALTER PROCEDURE [dbo].[name]
@start int = 0,
@stop int = 10,
@sortname varchar(100) = ‚ID‘,
@sortorder varchar(5) = ‚ASC‘,
@pocet int = 0

AS
BEGIN
DECLARE @script varchar(max)
DECLARE @sortorder1 varchar(5)
DECLARE @sortorder2 varchar(5)
DECLARE @stop2 int

IF @pocet < (@start+@stop) SET @stop2 = @pocet – @start ELSE SET @stop2 = @stop
IF @sortorder='ASC'
BEGIN
SET @sortorder1='DESC'
SET @sortorder2='ASC'
END ELSE
BEGIN
SET @sortorder1='ASC'
SET @sortorder2='DESC'
 END

SET @script=

select *
from (
select top '+str(@stop2)+‘ * from (
select top ‚+str(@start+@stop)+‘ *
from TABLE
order by ‚+@sortname+' '+@sortorder2+'
) as newtbl order by '+@sortname+' '+ @sortorder1+'
) as newtbl2
order by '+@sortname+' '+ @sortorder2+'

exec(@script)`
END

Editoval s.cerny67 (24. 7. 2014 22:31)