public function Upsert::__toString in Drupal driver for SQL Server and SQL Azure 8.2
Same name and namespace in other branches
- 8 drivers/lib/Drupal/Driver/Database/sqlsrv/Upsert.php \Drupal\Driver\Database\sqlsrv\Upsert::__toString()
- 3.0.x drivers/lib/Drupal/Driver/Database/sqlsrv/Upsert.php \Drupal\Driver\Database\sqlsrv\Upsert::__toString()
Implements PHP magic __toString method to convert the query to a string.
The toString operation is how we compile a query object to a prepared statement.
Return value
string A prepared statement query string for this object.
Overrides Query::__toString
File
- drivers/
lib/ Drupal/ Driver/ Database/ sqlsrv/ Upsert.php, line 74 - Contains \Drupal\Core\Database\Driver\sqlsrv\Upsert
Class
- Upsert
- Implements Native Upsert queries for MSSQL.
Namespace
Drupal\Driver\Database\sqlsrvCode
public function __toString() {
// Fetch the list of blobs and sequences used on that table.
$columnInformation = $this->connection
->schema()
->getTableIntrospection($this->table);
// Find out if there is an identity field set in this insert.
$setIdentity = !empty($columnInformation['identity']) && in_array($columnInformation['identity'], array_keys($this->insertFields));
$query = [];
$real_table = $this->connection
->prefixTable($this->table);
// Enable direct insertion to identity columns if necessary.
if ($setIdentity === true) {
$query[] = "SET IDENTITY_INSERT [{$real_table}] ON;";
}
$query[] = "MERGE INTO [{$real_table}] _target";
// 1. Implicit dataset
// select t.* from (values(1,2,3), (2,3,4)) as t(col1,col2,col3)
$values = $this
->getInsertPlaceholderFragment($this->insertValues, $this->defaultFields);
$columns = implode(', ', $this->connection
->quoteIdentifiers($this->insertFields));
$dataset = "SELECT T.* FROM (values" . implode(',', $values) . ") as T({$columns})";
// Build primery key conditions
$key_conditions = [];
// Fetch the list of blobs and sequences used on that table.
$primary_key_cols = array_column($columnInformation['indexes'][$columnInformation['primary_key_index']]['columns'], 'name');
foreach ($primary_key_cols as $key) {
$key_conditions[] = "_target.[{$key}] = _source.[{$key}]";
}
$query[] = "USING ({$dataset}) _source" . PHP_EOL . 'ON ' . implode(' AND ', $key_conditions);
// Mappings.
$insert_mappings = [];
$update_mappings = [];
foreach ($this->insertFields as $field) {
$insert_mappings[] = "_source.[{$field}]";
// Updating the unique / primary key is not necessary.
if (!in_array($field, $primary_key_cols)) {
$update_mappings[] = "_target.[{$field}] = _source.[{$field}]";
}
}
// "When matched" part
$query[] = 'WHEN MATCHED THEN UPDATE SET ' . implode(', ', $update_mappings);
// "When not matched" part.
$query[] = "WHEN NOT MATCHED THEN INSERT ({$columns}) VALUES (" . implode(', ', $insert_mappings) . ")";
// Return information about the query.
$query[] = 'OUTPUT $action;';
return implode(PHP_EOL, $query);
}