У меня проблема с запросом Pro * C, который я пытаюсь оптимизировать.
Для объяснения наше приложение ищет строки в огромной базе данных. Эти строки существуют на нескольких языках, и старый код выбирал строку для каждого языка в массиве. Теперь, когда эти запросы являются наиболее трудоемкой частью нашего приложения, я хотел сделать только один запрос, который записывает непосредственно в массив.
Коды языков представляют собой двухбуквенные коды ISO-639 (en для английского, fr для французского).
Старый способ (это только упрощенный код, показывающий намерение)
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];
}
Я бы хотел сделать что-то вроде этого:
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);
но не знаю, как мне определить LanCodes.
Он работает с постоянным списком (время компиляции), как это
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');
но это бесполезно, так как языки могут отличаться от случая к случаю.
Если я напишу что-то вроде
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);
работает, только если в строке 1 код языка.
Итак, мой вопрос: кто-нибудь знает, как заставить это работать? Документация по Oracle настолько велика, что я не знаю, где искать. Я пробовал разные способы, но ни один не работал.
EDIT
Хорошо, я нашел решение, которое работает. Это не элегантно, это не продвинуто, но работает хорошо. Я добавил в свой запрос список предложений OR, и он возвращает то, что мне нужно, в нужной форме.
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]);
Это быстрее, когда есть более двух языков, поэтому я называю этот вариант или старый, в зависимости от количества языков для выборки.