0

我正在尝试优化的 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

4 回答 4

1

如果没有Oracle Dynamic SQL ,您将无法做到这一点。您必须在运行时构建 IN 子句并立即执行。根据您的查询,至少您可以使用方法 1。

于 2009-11-17T15:46:19.560 回答
1

这篇AskTom 文章可能对您有所帮助。

于 2009-11-17T18:43:10.550 回答
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 ...并将其放入联接中。

于 2009-11-18T17:08:24.540 回答
0

... Main String:= 'Select * FROM table WHERE id=:uniqid AND language IN'; -- 可以一分为二来适应 :uniqd ... Select Language_code into v_string from x_table; loop Copy & Concat v_string to LanCode_String and with ' ', ; 结束循环;.. 将 Lancode 连接到主字符串。.. 准备并执行主字符串。

于 2009-11-19T16:33:12.370 回答