I am using Drupal 7.15 in Windows 7 with Oracle 11g Express Edition.

While enabling some modules, at certain point, I am getting the following error:

The website encountered an unexpected error. Please try again later.
DatabaseTransactionNoActiveException: in DatabaseConnection->rollback() (line 1019 of ..\includes\database\database.inc).

And after that, site is not accessible, until I disable the some modules manually, which I have tried to install at that time and then using update.php restore the menu system.

I dig down the problem and find out that it could be related to menu system.


I have trapped the error of the following SQLs in the menu.inc

$result = db_select('menu_links', NULL, array('fetch' => PDO::FETCH_ASSOC))
->fields('menu_links', array(
'link_path',
'mlid',
'router_path',
'updated',
))
->condition(db_or()
->condition('updated', 1)
->condition(db_and()
->condition('router_path', $paths, 'NOT IN')
->condition('external', 0)
->condition('customized', 1)
)
)
->execute();

$result = db_select('menu_links')
->fields('menu_links')
->condition('router_path', $paths, 'NOT IN')
->condition('external', 0)
->condition('updated', 0)
->condition('customized', 0)
->orderBy('depth', 'DESC')
->execute();

After trapping I am getting the following error:
OCIStmtExecute: ORA-01795: maximum number of expressions in a list is 1000

It means, $path variable has more then 1000 items, and "NOT IN" clause has a limit of 1000 expression, unless you use SQL which may generate more then 1000 expressions.

How to fix that?

Comments

aaaristo’s picture

look at the oracle_escape_long_in function in the 6.x driver... i should include that in 7.x

aaaristo’s picture

Status: Active » Needs work
aaaristo’s picture

Status: Needs work » Needs review

Commited, can you try the dev release?

yosriy’s picture

Hello,

I have same problem and this is not fixed on the latested version for now : 7.24

and I get : ORA-01000 maximum open cursors exceeded
As detailed on https://drupal.org/comment/359202#comment-359202

I already increased open_cursors as mentionned on :
http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10739/crea...

=> Via ToadForOracle :
sho parameter open_cursors
open_cursors integer 2000

I am available for more details,

For now no solution unfortunately...

Thnx,
Yosri

aaaristo’s picture

have you tried the -dev release?

fastturtle’s picture

Issue summary: View changes

Hello,

I have a drupal 7.31 installation on IIS7.5/WIN2008R2 and Oracle11g database. I am using the oracle driver.
I have installed the PM module and when I am trying to use it I am getting the same error as the issue's title.

Type php
Date Wednesday, October 1, 2014 - 13:56
User admin
Location http://localhost/testdrupal731/node/add/pmproject?render=overlay&render=...
Referrer http://localhost/testdrupal731/node/add/pmproject?render=overlay
Message DatabaseTransactionNoActiveException: in DatabaseConnection->rollback() (line 1038 of C:\inetpub\wwwroot\testdrupal731\includes\database\database.inc).
Severity error
Hostname ::1
Operations

Also I have test this with both recommended release and development release of oracle driver.
I have reported this issue also to the PM module's issues: https://www.drupal.org/node/2347685

Is there any possible solution to this?
Thanks in advance.

metallized’s picture

Hi i'm having the same issue using the 7.x-1.12+5-dev version of driver, there is news about this?, any help is much appreciated.

metallized’s picture

Status: Needs review » Needs work
metallized’s picture

Hi meanwhile i do this to the menu.inc file, I hope that soon there a patch:

/**
 * Builds menu links for the items in the menu router.
 */
function _menu_navigation_links_rebuild($menu) {
  // Add normal and suggested items as links.
  $menu_links = array();
  foreach ($menu as $path => $item) {
    if ($item['_visible']) {
      $menu_links[$path] = $item;
      $sort[$path] = $item['_number_parts'];
    }
  }
  if ($menu_links) {
    // Keep an array of processed menu links, to allow menu_link_save() to
    // check this for parents instead of querying the database.
    $parent_candidates = array();
    // Make sure no child comes before its parent.
    array_multisort($sort, SORT_NUMERIC, $menu_links);

    foreach ($menu_links as $key => $item) {
      $existing_item = db_select('menu_links')
        ->fields('menu_links')
        ->condition('link_path', $item['path'])
        ->condition('module', 'system')
        ->execute()->fetchAssoc();
      if ($existing_item) {
        $item['mlid'] = $existing_item['mlid'];
        // A change in hook_menu may move the link to a different menu
        if (empty($item['menu_name']) || ($item['menu_name'] == $existing_item['menu_name'])) {
          $item['menu_name'] = $existing_item['menu_name'];
          $item['plid'] = $existing_item['plid'];
        }
        else {
          // It moved to a new menu. Let menu_link_save() try to find a new
          // parent based on the path.
          unset($item['plid']);
        }
        $item['has_children'] = $existing_item['has_children'];
        $item['updated'] = $existing_item['updated'];
      }
      if ($existing_item && $existing_item['customized']) {
        $parent_candidates[$existing_item['mlid']] = $existing_item;
      }
      else {
        $item = _menu_link_build($item);
        menu_link_save($item, $existing_item, $parent_candidates);
        $parent_candidates[$item['mlid']] = $item;
        unset($menu_links[$key]);
      }
    }
  }
  $paths = array_keys($menu);
  //Start Path Oracle issue https://www.drupal.org/node/1804084
  if (count($paths) >= 1000) {
    $paths_pieces = array_chunk($paths, 900, TRUE);
  }
  // Updated and customized items whose router paths are gone need new ones.
  $result = db_select('menu_links', NULL, array('fetch' => PDO::FETCH_ASSOC))
    ->fields('menu_links', array(
      'link_path',
      'mlid',
      'router_path',
      'updated',
    ))
    ->condition(db_or()
      ->condition('updated', 1));
  if (isset($paths_pieces) && !empty($paths_pieces)) {
    foreach ($paths_pieces as $paths_piece) {
      $result->condition(db_and()
        ->condition('router_path', $paths_piece, 'NOT IN'));
    }
  }
  else {
    $result->condition(db_and()
      ->condition('router_path', $paths, 'NOT IN'));
  }

  $result->condition('external', 0)
    ->condition('customized', 1)
    ->execute();
  foreach ($result as $item) {
    $router_path = _menu_find_router_path($item['link_path']);
    if (!empty($router_path) && ($router_path != $item['router_path'] || $item['updated'])) {
      // If the router path and the link path matches, it's surely a working
      // item, so we clear the updated flag.
      $updated = $item['updated'] && $router_path != $item['link_path'];
      db_update('menu_links')
        ->fields(array(
          'router_path' => $router_path,
          'updated' => (int) $updated,
        ))
        ->condition('mlid', $item['mlid'])
        ->execute();
    }
  }
  // Find any item whose router path does not exist any more.
  $result = db_select('menu_links')
    ->fields('menu_links');
  if (isset($paths_pieces) && !empty($paths_pieces)) {
    foreach ($paths_pieces as $paths_piece) {
      $result->condition('router_path', $paths_piece, 'NOT IN');
    }
  }
  else {
    $result->condition('router_path', $paths, 'NOT IN');
  }
  $result->condition('external', 0)
    ->condition('updated', 0)
    ->condition('customized', 0)
    ->orderBy('depth', 'DESC')
    ->execute();
  // Remove all such items. Starting from those with the greatest depth will
  // minimize the amount of re-parenting done by menu_link_delete().
  foreach ($result as $item) {
    _menu_delete_item($item, TRUE);
  }
   //End Path Oracle issue https://www.drupal.org/node/1804084
}
metallized’s picture

Status: Needs work » Active
Issue tags: +menu_links, +menu.inc, +oracle, +oracle driver
yesmathew’s picture

Thanks #9, your trick worked on version 7.44. For me update.php was also not working with Oracle 11g, so following code fix on 2 files worked for me;

Code fix on include/update.inc -

function update_prepare_d7_bootstrap() {
  // Allow the bootstrap to proceed even if a Drupal 6 settings.php file is
  // still being used.
  include_once DRUPAL_ROOT . '/includes/install.inc';
  drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
  global $databases, $db_url, $db_prefix, $update_rewrite_settings;
  if (empty($databases) && !empty($db_url)) {
    $databases = update_parse_db_url($db_url, $db_prefix);
    // Record the fact that the settings.php file will need to be rewritten.
    $update_rewrite_settings = TRUE;
    $settings_file = conf_path() . '/settings.php';
    $writable = drupal_verify_install_file($settings_file, FILE_EXIST|FILE_READABLE|FILE_WRITABLE);
    $requirements = array(
      'settings file' => array(
        'title' => 'Settings file',
        'value' => $writable ? 'The settings file is writable.' : 'The settings file is not writable.',
        'severity' => $writable ? REQUIREMENT_OK : REQUIREMENT_ERROR,
        'description' => $writable ? '' : 'Drupal requires write permissions to <em>' . $settings_file . '</em> during the update process. If you are unsure how to grant file permissions, consult the <a href="http://drupal.org/server-permissions">online handbook</a>.',
      ),
    );
    update_extra_requirements($requirements);
  }

  // The new {blocked_ips} table is used in Drupal 7 to store a list of
  // banned IP addresses. If this table doesn't exist then we are still
  // running on a Drupal 6 database, so we suppress the unavoidable errors
  // that occur by creating a static list.
  $GLOBALS['conf']['blocked_ips'] = array();

  // Check that PDO is available and that the correct PDO database driver is
  // loaded. Bootstrapping to DRUPAL_BOOTSTRAP_DATABASE will result in a fatal
  // error otherwise.
  $message = '';
  $pdo_link = 'http://drupal.org/requirements/pdo';
  // PDO Driver Exceptions for Oracle, etc.
  $pdo_driver = $databases['default']['default']['driver'];
  switch ($pdo_driver) {
    case 'oracle':
        $pdo_driver = 'oci';
        break;
  }
  // Check that PDO is loaded.
  if (!extension_loaded('pdo')) {
    $message = '<h2>PDO is required!</h2><p>Drupal 7 requires PHP ' . DRUPAL_MINIMUM_PHP . ' or higher with the PHP Data Objects (PDO) extension enabled.</p>';
  }
  // The PDO::ATTR_DEFAULT_FETCH_MODE constant is not available in the PECL
  // version of PDO.
  elseif (!defined('PDO::ATTR_DEFAULT_FETCH_MODE')) {
    $message = '<h2>The wrong version of PDO is installed!</h2><p>Drupal 7 requires the PHP Data Objects (PDO) extension from PHP core to be enabled. This system has the older PECL version installed.';
    $pdo_link = 'http://drupal.org/requirements/pdo#pecl';
  }
  // Check that the correct driver is loaded for the database being updated.
  // If we have no driver information (for example, if someone tried to create
  // the Drupal 7 $databases array themselves but did not do it correctly),
  // this message will be confusing, so do not perform the check; instead, just
  // let the database connection fail in the code that follows.
  elseif (isset($databases['default']['default']['driver']) && !in_array($pdo_driver, PDO::getAvailableDrivers())) {
    $message = '<h2>A PDO database driver is required!</h2><p>You need to enable the PDO_' . strtoupper($pdo_driver) . ' database driver for PHP ' . DRUPAL_MINIMUM_PHP . ' or higher so that Drupal 7 can access the database.</p>';
  }
  if ($message) {
    print $message . '<p>See the <a href="' . $pdo_link . '">system requirements page</a> for more information.</p>';
    exit();
}

And code fix on include/menu.inc -

/**
 * Builds menu links for the items in the menu router.
 */
function _menu_navigation_links_rebuild($menu) {
  // Add normal and suggested items as links.
  $menu_links = array();
  foreach ($menu as $path => $item) {
    if ($item['_visible']) {
      $menu_links[$path] = $item;
      $sort[$path] = $item['_number_parts'];
    }
  }
  if ($menu_links) {
    // Keep an array of processed menu links, to allow menu_link_save() to
    // check this for parents instead of querying the database.
    $parent_candidates = array();
    // Make sure no child comes before its parent.
    array_multisort($sort, SORT_NUMERIC, $menu_links);

    foreach ($menu_links as $key => $item) {
      $existing_item = db_select('menu_links')
        ->fields('menu_links')
        ->condition('link_path', $item['path'])
        ->condition('module', 'system')
        ->execute()->fetchAssoc();
      if ($existing_item) {
        $item['mlid'] = $existing_item['mlid'];
        // A change in hook_menu may move the link to a different menu
        if (empty($item['menu_name']) || ($item['menu_name'] == $existing_item['menu_name'])) {
          $item['menu_name'] = $existing_item['menu_name'];
          $item['plid'] = $existing_item['plid'];
        }
        else {
          // It moved to a new menu. Let menu_link_save() try to find a new
          // parent based on the path.
          unset($item['plid']);
        }
        $item['has_children'] = $existing_item['has_children'];
        $item['updated'] = $existing_item['updated'];
      }
      if ($existing_item && $existing_item['customized']) {
        $parent_candidates[$existing_item['mlid']] = $existing_item;
      }
      else {
        $item = _menu_link_build($item);
        menu_link_save($item, $existing_item, $parent_candidates);
        $parent_candidates[$item['mlid']] = $item;
        unset($menu_links[$key]);
      }
    }
  }
  $paths = array_keys($menu);
  // Updated and customized items whose router paths are gone need new ones.
  // Also as Oracle 11g donot support over 1000 in an expression. Fixed using array_chunck() with 900.
  // For more info on Oracle issue, visit @ https://www.drupal.org/node/1804084
  $query = db_select('menu_links', NULL, array('fetch' => PDO::FETCH_ASSOC))
    ->fields('menu_links', array(
      'link_path',
      'mlid',
      'router_path',
      'updated',
    ))
    ->condition(db_or()
      ->condition('updated', 1));
    foreach(array_chunk($paths, 900, true) as $paths_chunk) {
      $query->condition(db_and()
        ->condition('router_path', $paths_chunk, 'NOT IN'));
    }
    $query->condition(db_and()
          ->condition('external', 0)
          ->condition('customized', 1));
  $result = $query->execute();

  foreach ($result as $item) {
    $router_path = _menu_find_router_path($item['link_path']);
    if (!empty($router_path) && ($router_path != $item['router_path'] || $item['updated'])) {
      // If the router path and the link path matches, it's surely a working
      // item, so we clear the updated flag.
      $updated = $item['updated'] && $router_path != $item['link_path'];
      db_update('menu_links')
        ->fields(array(
          'router_path' => $router_path,
          'updated' => (int) $updated,
        ))
        ->condition('mlid', $item['mlid'])
        ->execute();
    }
  }
  // Find any item whose router path does not exist any more.
  // Also as Oracle 11g donot support over 1000 in an expression. Fixed using array_chunck() with 900.
  // For more info on Oracle issue, visit @ https://www.drupal.org/node/1804084
  $query = db_select('menu_links')
    ->fields('menu_links');
    foreach(array_chunk($paths, 900, true) as $paths_chunk) {
       $query->condition('router_path', $paths_chunk, 'NOT IN');
    }
    $query->condition('external', 0)
          ->condition('updated', 0)
          ->condition('customized', 0)
          ->orderBy('depth', 'DESC');
  $result = $query->execute();
    // Remove all such items. Starting from those with the greatest depth will
  // minimize the amount of re-parenting done by menu_link_delete().
  foreach ($result as $item) {
    _menu_delete_item($item, TRUE);
  }
}
punch’s picture

Instead of changing the menu.inc try this: https://www.drupal.org/node/2761515

bohart’s picture

Version: 7.x-1.12 » 7.x-1.x-dev
Status: Active » Closed (outdated)

D7 reached its EOL back in January 2025, and there is no active release for D7 for this module anymore.
Development or support is not planned for D7. All D7-related issues are marked as outdated in a bunch.

Everyone can apply the patches/suggestions above (not tested by the maintainers, tested by the community) to their D7 projects.
If the issue remains relevant for D10+ versions, merge requests with proposed solutions for a new module version (D10+) are welcome in a new follow-up issue.

Thanks!

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.