如何在Pro * C查询中指定变量表达式列表?

时间:2009-11-17 15:34:36

标签: c oracle embedded-database oracle-pro-c

我正在尝试优化Pro * C查询。

为了解释,我们的应用程序在一个巨大的数据库中搜索行。这些行以多种语言存在,旧代码为数组中的每种语言选择一行。现在因为这些查询是我们应用程序中最耗时的部分,所以我只想制作一个直接写入数组的查询。

语言代码是2个字母的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文档太大了,我不知道在哪里看。我尝试了不同的方法,但都没有用。

修改 好的,我找到了一个有效的解决方案。它不优雅,它没有先进但它运作良好。我在查询中放了一个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]);

当有超过2种语言时,它会更快,所以我根据要获取的语言数量来调用此变体或旧变体。

4 个答案:

答案 0 :(得分:1)

如果没有Oracle Dynamic SQL,则无法执行此操作。您必须在运行时和EXECUTE IMMEDIATE构建IN子句。至少你可以根据你的查询使用方法1。

答案 1 :(得分:1)

可能这AskTom article可以帮到你。

答案 2 :(得分:0)

我在使用表之前使用了一个ID和一组行,其中行是“in”列表中可能值的排列。然后我加入到基于的表 ID,它给了我需要的结果。

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

然后你需要做的就是选择正确的“ID”值2,3,4 ...并将其放入 加入。

答案 3 :(得分:0)

... Main String:='Select * FROM table WHERE id =:uniqid AND language IN'; - 可以拆分为两个适合:uniqd ... 选择Language_code到v_string 来自x_table; 环  复制&amp; Concat v_string到LanCode_String并带'',; 结束循环; .. Concat Lancode到主字符串。 .. 准备并执行主字符串。