Indique le nombre de lignes qui doivent être lues à l'avance par Oracle

# oci_set_prefetch

(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)

oci_set_prefetch — Indique le nombre de lignes qui doivent être lues à l'avance par Oracle

### Description

function oci_set_prefetch(resource `$statement`, int `$rows`): bool

Définit le nombre de lignes à précharger par les bibliothèques clientes Oracle après un appel réussi à la fonction oci_execute() mais aussi pour chaque appel aux fonctions internes de récupération de lignes à la base de données. Pour les requêtes retournant un grand nombre de lignes, les performances peuvent être significativement améliorées en augmentant le nombre de lignes à précharger par rapport à la valeur par défaut définie par l'option de configuration oci8.default_prefetch.

Le préchargement est une façon efficace de retourner plus d'une ligne de données depuis la base de données pour chaque envoi réseau. Il en retourne une meilleure utilisation du réseau mais aussi une meilleure utilisation du CPU. Le préchargement de lignes est interne à OCI8 et le comportement des fonctions de récupération de données reste inchangé suivant la valeur du compteur de préchargement. Par exemple, la fonction oci_fetch_row() retournera toujours une ligne. Le buffer de préchargement est propre à chaque requête et ne sera pas utilisé pour ré-exécuter des requêtes ou par les autres connexions.

Il convient d'appeler la fonction oci_set_prefetch() avant la fonction oci_execute().

Un des moyens de gagner en efficacité est de définir la valeur de préchargement à une valeur raisonnable en fonction du réseau et de la base de données à gérer. Pour les requêtes retournant un très grand nombre de lignes, il convient de récupérer l'ensemble des lignes par morceaux (c.-à-d. définir la valeur de préchargement à une valeur en dessous du nombre total de lignes). Ceci permet à la base de données de gérer les requêtes des autres utilisateurs pendant que le script PHP gère le jeu de lignes courant.

Le préchargement a été introduit en Oracle 8i. Le préchargement `REF CURSOR` a été introduit en Oracle 11gR2 et est disponible lorsque PHP est lié avec les bibliothèques clientes Oracle 11gR2 (ou supérieur). Les curseurs imbriqués de préchargement ont été introduits en Oracle 11gR2 et nécessitent à la fois les bibliothèques clientes Oracle, et une base de données en version 11gR2 (ou supérieur).

Le préchargement n'est pas supporté lorsque les requêtes contiennent des colonnes de type LONG ou LOB. La valeur de préchargement sera utilisée dans toutes les situations où le préchargement est supporté.

Lors de l'utilisation de la base de données Oracle 12c, le jeu de valeurs préchargées par PHP peut être écrasé par le fichier de configuration client d'Oracle `oraaccess.xml`. Se référer à la documentation d'Oracle pour plus de détails.

### Liste de paramètres

`statement`
  Un identifiant de requête OCI8 créé par la fonction oci_parse() et exécuté par la fonction oci_execute(), ou un identifiant de requête `REF CURSOR`.
`rows`

  Le nombre de lignes à précharger, >=0

### Valeurs de retour

Cette fonction retourne `true` en cas de succès ou `false` si une erreur survient.

### Exemples

Exemple #1 Modification de la valeur de préchargement pour une requête

    <?php

    $conn = oci_connect('hr', 'welcome', 'localhost/XE');

    $stid = oci_parse($conn, 'SELECT * FROM myverybigtable');
    oci_set_prefetch($stid, 300);  // A définir avant l'appel à la fonction oci_execute()
    oci_execute($stid);

    echo "<table border='1'>\n";
    while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
        echo "<tr>\n";
        foreach ($row as $item) {
            echo "    <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : "")."</td>\n";
        }
        echo "</tr>\n";
    }
    echo "</table>\n";

    oci_free_statement($stid);
    oci_close($conn);

    ?>

Exemple #2 Modification de la valeur de préchargement pour une récupération REF CURSOR

    <?php
    /*
      Création de la procédure stockée PL/SQL suivante :

      CREATE OR REPLACE PROCEDURE myproc(p1 OUT SYS_REFCURSOR) AS
      BEGIN
        OPEN p1 FOR SELECT * FROM all_objects WHERE ROWNUM < 5000;
      END;
    */

    $conn = oci_connect('hr', 'welcome', 'localhost/XE');

    $stid = oci_parse($conn, 'BEGIN myproc(:rc); END;');
    $refcur = oci_new_cursor($conn);
    oci_bind_by_name($stid, ':rc', $refcur, -1, OCI_B_CURSOR);
    oci_execute($stid);

    // Modification de la valeur de préchargement avant l'exécution du curseur.
    // Le préchargement REF CURSOR fonctionne lorsque PHP est lié avec les bibliothèques clientes
    // Oracle 11gR2 (ou supérieur)
    oci_set_prefetch($refcur, 200);
    oci_execute($refcur);

    echo "<table border='1'>\n";
    while ($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) {
        echo "<tr>\n";
        foreach ($row as $item) {
            echo "    <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : "")."</td>\n";
        }
        echo "</tr>\n";
    }
    echo "</table>\n";

    oci_free_statement($refcur);
    oci_free_statement($stid);
    oci_close($conn);

    ?>

Si PHP OCI8 récupère des données depuis un curseur `REF CURSOR` puis, retourne le curseur `REF CURSOR` à une seconde procédure stockée pour traitement, alors il convient de définir le préchargement de `REF CURSOR` à `0` afin d'éviter de perdre des lignes du jeu de résultats. La valeur de préchargement est le nombre de lignes supplémentaire à récupérer pour chaque requête interne OCI8 à la base de données, aussi, le fait de la définir à `0` signifie uniquement que nous souhaitons récupérer une seule ligne à la fois.

Exemple #3 Définition de la valeur de préchargement lorsque l'on retourne un curseur `REF CURSOR` à Oracle

    <?php

    $conn = oci_connect('hr', 'welcome', 'localhost/orcl');

    // Récupération du curseur REF CURSOR
    $stid = oci_parse($conn, 'BEGIN myproc(:rc_out); END;');
    $refcur = oci_new_cursor($conn);
    oci_bind_by_name($stid, ':rc_out', $refcur, -1, OCI_B_CURSOR);
    oci_execute($stid);

    // Affiche 2 lignes, mais ne précharge pas de lignes supplémentaires
    // sinon, ces lignes supplémentaires ne seront pas passées à myproc_use_rc().
    oci_set_prefetch($refcur, 0);
    oci_execute($refcur);
    $row = oci_fetch_array($refcur);
    var_dump($row);
    $row = oci_fetch_array($refcur);
    var_dump($row);

    // passe le curseur REF CURSOR à myproc_use_rc() afin d'effectuer d'autres
    // traitement sur le jeu de résultats
    $stid = oci_parse($conn, 'begin myproc_use_rc(:rc_in); end;');
    oci_bind_by_name($stid, ':rc_in', $refcur, -1, OCI_B_CURSOR);
    oci_execute($stid);

    ?>

### Voir aussi

- l'option de configuration oci8.default_prefetch

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open