picodb(mssql): teach picodb to use TOP for limits on MSSQL

This commit is contained in:
Joe Nahmias
2022-07-08 15:32:29 -04:00
committed by Frédéric Guillot
parent 5493c2997e
commit 37bc859df5
3 changed files with 38 additions and 2 deletions

View File

@@ -30,6 +30,14 @@ abstract class Base
*/ */
protected $pdo = null; protected $pdo = null;
/**
* use TOP or LIMIT for returning a subset of rows
*
* @access public
* @var bool
*/
public bool $useTop;
/** /**
* Create a new PDO connection * Create a new PDO connection
* *
@@ -128,6 +136,7 @@ abstract class Base
$this->createConnection($settings); $this->createConnection($settings);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->useTop = false;
} }
/** /**
@@ -231,4 +240,5 @@ abstract class Base
{ {
return $this->getConnection()->query('SELECT VERSION()')->fetchColumn(); return $this->getConnection()->query('SELECT VERSION()')->fetchColumn();
} }
} }

View File

@@ -25,6 +25,18 @@ class Mssql extends Base
'database', 'database',
); );
/**
* Constructor
*
* @access public
* @param array $settings
*/
public function __construct(array $settings)
{
parent::__construct($settings);
$this->useTop = true;
}
/** /**
* Table to store the schema version * Table to store the schema version
* *
@@ -180,4 +192,5 @@ class Mssql extends Base
$this->getConnection()->exec('SET SHOWPLAN_ALL ON'); $this->getConnection()->exec('SET SHOWPLAN_ALL ON');
return $this->getConnection()->query($this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC); return $this->getConnection()->query($this->getSqlFromPreparedStatement($sql, $values))->fetchAll(PDO::FETCH_ASSOC);
} }
} }

View File

@@ -119,6 +119,14 @@ class Table
*/ */
private $sqlSelect = ''; private $sqlSelect = '';
/**
* SQL TOP clause
*
* @access private
* @var string
*/
private $sqlTop = '';
/** /**
* SQL joins * SQL joins
* *
@@ -578,7 +586,11 @@ class Table
public function limit($value) public function limit($value)
{ {
if (! is_null($value)) { if (! is_null($value)) {
$this->sqlLimit = ' LIMIT '.(int) $value; if ($this->db->getDriver()->useTop) {
$this->sqlTop = ' TOP ('.(int) $value.') ';
} else {
$this->sqlLimit = ' LIMIT '.(int) $value;
}
} }
return $this; return $this;
@@ -693,7 +705,8 @@ class Table
$this->groupBy = $this->db->escapeIdentifierList($this->groupBy); $this->groupBy = $this->db->escapeIdentifierList($this->groupBy);
return trim(sprintf( return trim(sprintf(
'SELECT %s FROM %s %s %s %s %s %s %s', 'SELECT %s %s FROM %s %s %s %s %s %s %s',
$this->sqlTop,
$this->sqlSelect, $this->sqlSelect,
$this->db->escapeIdentifier($this->name), $this->db->escapeIdentifier($this->name),
implode(' ', $this->joins), implode(' ', $this->joins),