Pergunta

Tenho um problema com uma consulta profissional que estou tentando otimizar.

Para explicar, nosso aplicativo pesquisa linhas em um grande banco de dados. Essas linhas existem em vários idiomas e o código antigo selecionou uma linha para cada idioma em uma matriz. Agora, como essas consultas são a parte mais demorada do nosso aplicativo, eu queria fazer apenas uma consulta que grava diretamente em uma matriz.

Os códigos de idioma são 2 códigos ISO-639 (pt para inglês, FR para o francês).

Velho Caminho (este é apenas um código simplificado para mostrar a intenção)

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];
}

Eu gostaria de fazer algo assim:

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);

Mas não sei como devo definir Lancodes.

Funciona com uma lista constante (tempo de compilação) como esta

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');

Mas isso não é útil, pois os idiomas podem variar de caso para caso.

Se eu escrever algo como

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);

Funciona apenas se houver 1 código de idioma na sequência.

Então, minha pergunta é: alguém sabe como fazer isso funcionar? A documentação do Oracle é tão grande que não sei para onde olhar. Eu tentei maneiras diferentes, mas nenhuma funcionou.

EDITAROk, encontrei uma solução que funciona. Não é elegante, não é avançado, mas funciona bem. Coloquei uma lista ou cláusulas na minha consulta e ela retorna o que preciso no formulário que preciso.

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]);

É mais rápido quando há mais de 2 idiomas, então eu chamo essa variante ou a antiga, dependendo do número de idiomas para buscar.

Foi útil?

Solução

Provavelmente isso Artigo de Asktom pode ajudá -lo.

Outras dicas

Você não pode fazer isso sem Oracle Dynamic SQL. Você terá que construir sua cláusula no tempo de execução e executar imediato. Pelo menos você pode usar o método 1, com base em suas consultas.

Eu usei uma tabela antes de composta por um ID e um conjunto de linhas, onde as linhas são a permutação dos possíveis valores na lista "In". Então eu me junto à tabela com base no ID e isso me dá os resultados de que preciso.

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' );
...

Tudo o que você precisa fazer é escolher o valor correto "ID" 2, 3, 4 ... e colocá -lo na junção.

... string principal: = 'Selecione * da tabela onde id =: uniqid e idioma em'; - pode se dividir em dois para acompanhar: uniqd ... selecione idioma_code em v_string de x_table; Cópia de loop e concat v_string para lancode_string e com '' ,; loop final; .. Concate Lancode para a string principal. .. Prepare e execute a sequência principal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top