public function MergeQuery_sqlsrv::execute in Drupal driver for SQL Server and SQL Azure 7.2
Same name and namespace in other branches
- 7.3 sqlsrv/query.inc \MergeQuery_sqlsrv::execute()
- 7 sqlsrv/query.inc \MergeQuery_sqlsrv::execute()
Runs the query against the database.
Overrides MergeQuery::execute
File
- sqlsrv/
query.inc, line 357
Class
- MergeQuery_sqlsrv
- SQL Server-specific implementation of the MERGE operation.
Code
public function execute() {
if (!count($this->condition)) {
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
}
// Retrieve query options.
$options = $this->queryOptions;
// Keep a reference to the blobs.
$blobs = array();
// Fetch the list of blobs and sequences used on that table.
$columnInformation = $this->connection
->schema()
->queryColumnInformation($this->table);
// Find out if there is an identity field set in this insert.
$this->setIdentity = !empty($columnInformation['identity']) && in_array($columnInformation['identity'], array_keys($this->insertFields));
// Initialize placeholder count.
$max_placeholder = 0;
// Build the query.
$stmt = $this->connection
->prepareQuery((string) $this);
// Build the arguments: 1. condition.
$arguments = $this->condition
->arguments();
DatabaseUtils::BindArguments($stmt, $arguments);
// 2. When matched part.
$fields = $this->updateFields;
DatabaseUtils::BindExpressions($stmt, $this->expressionFields, $fields);
DatabaseUtils::BindValues($stmt, $fields, $blobs, ':db_merge_placeholder_', $columnInformation, $max_placeholder);
// 3. When not matched part.
DatabaseUtils::BindValues($stmt, $this->insertFields, $blobs, ':db_merge_placeholder_', $columnInformation, $max_placeholder);
// 4. Run the query, this will return UPDATE or INSERT
// MERGE queries should be atomic, yet you can run into concurrency
// issues, so implement some retry logic. This is more elaborate and generic
// in the 8.x-2.x version of the driver, just a quick workaround here.
try {
$this->connection
->query($stmt, [], $options);
} catch (\PDOException $e) {
if (in_array((string) $e
->getCode(), [
'23000',
])) {
// Try again...
$this->connection
->query($stmt, [], $options);
}
else {
// Rethrow.
throw $e;
}
}
$result = NULL;
foreach ($stmt as $value) {
$result = $value->{'$action'};
}
switch ($result) {
case 'UPDATE':
return static::STATUS_UPDATE;
case 'INSERT':
return static::STATUS_INSERT;
}
}