Commit 019e114a authored by Sergei Morozov's avatar Sergei Morozov Committed by Marco Pivetta

[DBAL-2546] Keep track of bound variables in SQLSrvStatement

parent c3fb1842
...@@ -53,11 +53,18 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -53,11 +53,18 @@ class SQLSrvStatement implements IteratorAggregate, Statement
private $stmt; private $stmt;
/** /**
* Parameters to bind. * References to the variables bound as statement parameters.
* *
* @var array * @var array
*/ */
private $params = array(); private $variables = array();
/**
* Bound parameter types.
*
* @var array
*/
private $types = array();
/** /**
* Translations. * Translations.
...@@ -145,11 +152,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -145,11 +152,8 @@ class SQLSrvStatement implements IteratorAggregate, Statement
throw new SQLSrvException("sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead."); throw new SQLSrvException("sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.");
} }
if ($type === \PDO::PARAM_LOB) { $this->variables[$column] =& $variable;
$this->params[$column-1] = array($variable, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), SQLSRV_SQLTYPE_VARBINARY('max')); $this->types[$column] = $type;
} else {
$this->params[$column-1] = $variable;
}
} }
/** /**
...@@ -211,12 +215,16 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -211,12 +215,16 @@ class SQLSrvStatement implements IteratorAggregate, Statement
$hasZeroIndex = array_key_exists(0, $params); $hasZeroIndex = array_key_exists(0, $params);
foreach ($params as $key => $val) { foreach ($params as $key => $val) {
$key = ($hasZeroIndex && is_numeric($key)) ? $key + 1 : $key; $key = ($hasZeroIndex && is_numeric($key)) ? $key + 1 : $key;
$this->bindValue($key, $val); $this->variables[$key] = $val;
$this->types[$key] = null;
} }
} }
$this->stmt = sqlsrv_query($this->conn, $this->sql, $this->params);
if ( ! $this->stmt) { if ( ! $this->stmt) {
$this->stmt = $this->prepare();
}
if (!sqlsrv_execute($this->stmt)) {
throw SQLSrvException::fromSqlSrvErrors(); throw SQLSrvException::fromSqlSrvErrors();
} }
...@@ -229,6 +237,38 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -229,6 +237,38 @@ class SQLSrvStatement implements IteratorAggregate, Statement
$this->result = true; $this->result = true;
} }
/**
* Prepares SQL Server statement resource
*
* @return resource
* @throws SQLSrvException
*/
private function prepare()
{
$params = array();
foreach ($this->variables as $column => &$variable) {
if ($this->types[$column] === \PDO::PARAM_LOB) {
$params[$column - 1] = array(
&$variable,
SQLSRV_PARAM_IN,
SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY),
SQLSRV_SQLTYPE_VARBINARY('max'),
);
} else {
$params[$column - 1] =& $variable;
}
}
$stmt = sqlsrv_prepare($this->conn, $this->sql, $params);
if (!$stmt) {
throw SQLSrvException::fromSqlSrvErrors();
}
return $stmt;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -151,6 +151,23 @@ EOF ...@@ -151,6 +151,23 @@ EOF
$this->assertEquals(2, $id); $this->assertEquals(2, $id);
} }
public function testReuseStatementWithParameterBoundByReference()
{
$this->_conn->insert('stmt_test', array('id' => 1));
$this->_conn->insert('stmt_test', array('id' => 2));
$stmt = $this->_conn->prepare('SELECT id FROM stmt_test WHERE id = ?');
$stmt->bindParam(1, $id);
$id = 1;
$stmt->execute();
$this->assertEquals(1, $stmt->fetchColumn());
$id = 2;
$stmt->execute();
$this->assertEquals(2, $stmt->fetchColumn());
}
/** /**
* @dataProvider emptyFetchProvider * @dataProvider emptyFetchProvider
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment