Question

J'ai un problème avec une requête Pro * C Je suis en train d'optimiser.

Pour expliquer, nos recherches d'application pour les lignes dans une base de données énorme. Ces lignes existent en plusieurs langues et l'ancien code sélectionné une ligne pour chaque langue dans un tableau. Maintenant que ces requêtes sont le plus de temps de notre application, je voulais faire une seule requête qui écrit directement dans un tableau.

Les codes de langue sont 2 lettres ISO-639 codes (en pour l'anglais, fr pour le français).

Ancien chemin (ce qui est seulement un code simplifié pour montrer l'intention)

struct ROW arr[MAX_LAN];
struct ROW_IND arr_ind[MAX_LAN];
uint_t LanIdx;
for(LanIdx=0; LanIdx<MAX_LAN; LanIdx++) {
  EXEC SQL SELECT *  /* Don't look at the *, it's for obfuscation only */
      INTO :arr[LanIdx]:arr_ind[LanIdx]
      FROM table WHERE id=:uniqid AND language=:LanCode[LanIdx];
}

Je voudrais faire quelque chose comme ceci:

EXEC SQL SELECT *  /* Don't look at the *, it's for obfuscation only */
    INTO :arr:arr_ind
    FROM table WHERE id=:uniqid AND language IN (:LanCodes);

mais ne sais pas comment je dois définir LanCodes.

Il fonctionne avec une liste constante (compilation) comme ceci

EXEC SQL SELECT *  /* Don't look at the *, it's for obfuscation only */
    INTO :arr:arr_ind
    FROM table WHERE id=:uniqid AND language IN ('en','fr','de');

mais ce n'est pas utile, car les langues peuvent varier d'un cas à l'autre.

Si j'écris quelque chose comme

char LanCodes[MAX_LANS*5];
sprintf(LanCodes, "%s", LanCode[LanIdx]);

EXEC SQL SELECT *  /* Don't look at the *, it's for obfuscation only */
    INTO :arr:arr_ind
    FROM table WHERE id=:uniqid AND language IN (:LanCodes);

il ne fonctionne que s'il y a 1 code de langue dans la chaîne.

Alors ma question est, quelqu'un sait comment faire ce travail? La documentation Oracle est si grand, je ne sais pas où regarder. J'ai essayé différentes façons, mais aucun travaillé.

EDIT Ok, j'ai trouvé une solution qui fonctionne. Ce n'est pas élégant, ce n'est pas avancé, mais il fonctionne bien. Je mets une liste de clauses ou dans ma requête et renvoie ce que je dois sous la forme que j'ai besoin.

EXEC SQL SELECT *  /* Don't look at the *, it's for obfuscation only */
    INTO :arr:arr_ind
    FROM table WHERE id=:uniqid AND (
                language=:v1[ 0] OR
                language=:v1[ 1] OR
                language=:v1[ 2] OR
                language=:v1[ 3] OR
                language=:v1[ 4] OR
                language=:v1[ 5] OR
                language=:v1[ 6] OR
                language=:v1[ 7] OR
                language=:v1[ 8] OR
                language=:v1[ 9] OR
                language=:v1[10] OR
                language=:v1[11] OR
                language=:v1[12] OR
                language=:v1[13] OR
                language=:v1[14] OR
                language=:v1[15] OR
                language=:v1[16] OR
                language=:v1[17] OR
                language=:v1[18] OR
                language=:v1[19] OR
                language=:v1[20] OR
                language=:v1[21] OR
                language=:v1[22] OR
                language=:v1[23] OR
                language=:v1[24] OR
                language=:v1[25] OR
                language=:v1[26] OR
                language=:v1[27] OR
                language=:v1[28] OR
                language=:v1[29] OR
                language=:v1[30]);

Il est plus rapide quand il y a plus de 2 langues, je donne la parole cette variante ou l'ancien selon le nombre de langues à extraire.

Était-ce utile?

La solution

Probablement cette AskTom article peut vous aider.

Autres conseils

Vous ne pouvez pas le faire sans Oracle SQL dynamique . Vous devrez construire votre clause IN lors de l'exécution et EXECUTE IMMEDIATE. Au moins, vous pouvez utiliser la méthode 1, en fonction de vos requêtes.

Je l'ai utilisé une table avant composée d'un ID et un ensemble de lignes où les lignes sont la permutation des valeurs possibles dans la liste « dans ». Ensuite, je me joins à la table en fonction de la ID et il me donne les résultats dont j'ai besoin.

create table permute (
  id number,
  lang char(2)
);
create index permute_p1 on permute ( lang, id );
insert into permute ( id, lang ) values ( 1, 'en' );
insert into permute ( id, lang ) values ( 2, 'en' );
insert into permute ( id, lang ) values ( 2, 'fr' );
...

Tout ce que vous avez à faire est de choisir alors la valeur « ID » correcte 2, 3, 4 ... et mettez-le dans joindre.

... Chaîne principale: = 'SELECT * FROM table WHERE id =: uniqid et le langage'; - peut diviser en deux à accueilleraient: uniqd ... Sélectionnez LANGUAGE_CODE dans v_string de x_table; boucle  Copier & Concat v_string à LanCode_String et '',; boucle fin; .. Concat Lancode à la page principale chaîne. .. Préparer et exécuter la chaîne principale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top