You are here

public function InsertQuery_sqlsrv::execute in Drupal driver for SQL Server and SQL Azure 7

Same name and namespace in other branches
  1. 7.3 sqlsrv/query.inc \InsertQuery_sqlsrv::execute()
  2. 7.2 sqlsrv/query.inc \InsertQuery_sqlsrv::execute()

Executes the insert query.

Return value

The last insert ID of the query, if one exists. If the query was given multiple sets of values to insert, the return value is undefined. If no fields are specified, this method will do nothing and return NULL. That makes it safe to use in multi-insert loops.

Overrides InsertQuery::execute

File

sqlsrv/query.inc, line 11

Class

InsertQuery_sqlsrv
SQL Server-specific implementation of INSERT.

Code

public function execute() {
  if (!$this
    ->preExecute()) {
    return NULL;
  }

  // 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.
  foreach ($this->insertFields as $field) {
    if (isset($columnInformation['identities'][$field])) {
      $this->setIdentity = TRUE;
    }
  }

  // Each insert happens in its own query. However, we wrap it in a transaction
  // so that it is atomic where possible.
  if (empty($this->queryOptions['sqlsrv_skip_transactions'])) {
    $transaction = $this->connection
      ->startTransaction();
  }
  if (!empty($this->fromQuery)) {

    // Re-initialize the values array so that we can re-use this query.
    $this->insertValues = array();
    $stmt = $this->connection
      ->PDOPrepare($this->connection
      ->prefixTables((string) $this));

    // Handle the case of SELECT-based INSERT queries first.
    $values = $this->fromQuery
      ->getArguments();
    foreach ($values as $key => $value) {
      $stmt
        ->bindParam($key, $values[$key]);
    }
    try {
      $stmt
        ->execute();
    } catch (Exception $e) {

      // This INSERT query failed, rollback everything if we started a transaction earlier.
      if (!empty($transaction)) {
        $transaction
          ->rollback();
      }

      // Rethrow the exception.
      throw $e;
    }
    return $this->connection
      ->lastInsertId();
  }

  // Handle the case of full-default queries.
  if (empty($this->fromQuery) && (empty($this->insertFields) || empty($this->insertValues))) {

    // Re-initialize the values array so that we can re-use this query.
    $this->insertValues = array();
    $stmt = $this->connection
      ->PDOPrepare($this->connection
      ->prefixTables('INSERT INTO {' . $this->table . '} DEFAULT VALUES'));
    try {
      $stmt
        ->execute();
    } catch (Exception $e) {

      // This INSERT query failed, rollback everything if we started a transaction earlier.
      if (!empty($transaction)) {
        $transaction
          ->rollback();
      }

      // Rethrow the exception.
      throw $e;
    }
    return $this->connection
      ->lastInsertId();
  }
  $query = (string) $this;
  $stmt = $this->connection
    ->PDOPrepare($this->connection
    ->prefixTables($query));

  // We use this array to store references to the blob handles.
  // This is necessary because the PDO will otherwise messes up with references.
  $data_values = array();
  foreach ($this->insertValues as $insert_index => $insert_values) {
    $max_placeholder = 0;
    foreach ($this->insertFields as $field_index => $field) {
      $placeholder = ':db_insert' . $max_placeholder++;
      if (isset($columnInformation['blobs'][$field])) {
        $data_values[$placeholder . $insert_index] = fopen('php://memory', 'a');
        fwrite($data_values[$placeholder . $insert_index], $insert_values[$field_index]);
        rewind($data_values[$placeholder . $insert_index]);
        $stmt
          ->bindParam($placeholder, $data_values[$placeholder . $insert_index], PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
      }
      else {
        $data_values[$placeholder . $insert_index] = $insert_values[$field_index];
        $stmt
          ->bindParam($placeholder, $data_values[$placeholder . $insert_index]);
      }
    }
    try {
      $stmt
        ->execute();
    } catch (Exception $e) {

      // This INSERT query failed, rollback everything if we started a transaction earlier.
      if (!empty($transaction)) {
        $transaction
          ->rollback();
      }

      // Rethrow the exception.
      throw $e;
    }
    $last_insert_id = $this->connection
      ->lastInsertId();
  }

  // Re-initialize the values array so that we can re-use this query.
  $this->insertValues = array();
  return $last_insert_id;
}