进度4gl:如何从满足多个关键字

时间:2015-05-13 09:18:59

标签: progress-4gl

   ID   CODE        STATE   CITY            AREA
    1   SBIN0000952 ORISSA  JAIPUR          TOWN
    2   SBIN0000953 ORISSA  KURAPUT         VILLAGE
    3   SBIN0000954 DELHI   DELHI           TOWN
    4   SBIN0000955 DELHI   NEW DELHI       VILLAGE
    5   SBIN0000956 GOA     SOUTH GOA       VILLAGE
    6   SBIN0000957 GOA     PANAJI          TOWN
    7   SBIN0000958 KERLA   CHOCHIN         TOWN
    8   SBIN0000959 KERLA   TRIVANDRAM      VILLAGE
    9   SBIN0000960 ANDHRA  VIZAG           TOWN
    10  SBIN0000961 ANDHRA  HYDERABAD       VILLAGE

鉴于上述数据,我想搜索"关键字"由用户输入的。例如,用户可能会提供" kerla,town"。

程序应显示记录:

7   SBIN0000958 KERLA   CHOCHIN    TOWN

如果输入了多个关键字,则只显示包含所有关键字的记录。

4 个答案:

答案 0 :(得分:0)

选项1: 查找有关构造动态查询的文档,并为您关注的字段和输入值的每个组合构建所有各种相等匹配。这可能不太好或表现不佳。

选项2: 向表中添加另一个字符字段,并将可搜索字段中的所有值放入其中。在该字段上构建一个单词索引,并查看CONTAINS的文档。它是专门用于使用单词索引来查找文本字符串的确切出现的构建。

我过去曾经多次使用过选项2,只要你能确保单词索引字段得到妥善维护并且可以处理一些限制,那么它运行良好且非常快。

答案 1 :(得分:0)

首先,抱歉延误。 现在,我设计了一些对你有用的东西:

define temp-table ttTable
    field id as integer
    field state as character
    field city  as character
    field area  as character
    index idx is primary unique id.

DEFINE VARIABLE cKeyWords AS CHARACTER   NO-UNDO.
DEFINE VARIABLE i         AS INTEGER     NO-UNDO.
DEFINE VARIABLE hBuffer   AS HANDLE      NO-UNDO.

DEFINE VARIABLE cStateLst AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cCityLst  AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cAreaLst  AS CHARACTER   NO-UNDO.

/* These variables are just to load the temp-table for the example */
cStateLst = 'Orissa,Orissa,Delhi,Delhi,Goa,Goa,Kerla,Kerla,Andhra,Andhra'.
cCityLst = 'Jaipur,Kuraput,Delhi,New Delhi,South Goa,Panaji,Chochin,Trivandram,Vizag,Hyderabad'.
cAreaLst = 'Town,Village,Town,Village,Village,Town,Town,Village,Town,Village'.
do i = 1 to 10:
   create ttTable.
   assign ttTable.id = i
          ttTable.state = entry(i,cStateLst)
          ttTable.city = entry(i,cCityLst)
          ttTable.area = entry(i,cAreaLst).
end.
/* For your real code, you don't need this loading part. */

update cKeyWords format "x(20)".
/* now trim the comma separated list to avoid mismatches */
do  i = 1 to num-entries(cKeyWords):
    assign entry(i,cKeyWords) = trim(entry(i,cKeyWords)).
end.
/* trailing and leading spaces eliminated, let's begin */
assign hBuffer = temp-table ttTable:default-buffer-handle.
for each ttTable:
    do i = 1 to hBuffer:num-fields:
       if lookup(string(hBuffer:buffer-field(i):buffer-value()), cKeyWords) > 0 then
          display ttTable.
    end.
end.

请注意,它适用于临时表。使其与表一起使用的唯一显着变化是此行assign hBuffer = temp-table ttTable:default-buffer-handle.应为

assign hBuffer = buffer <yourtable>:handle.

其他一些说明: 我正在循环这些字段并在显示之前将它们转换为字符串。这明显慢于动态构建查询,但由于您甚至不知道它们将查询哪些字段,我认为这是最好的方法。 仍然,它应该比具有适当的查询慢得多。因此,考虑一个用户还可以识别他们想要过滤的字段的界面,可以让您构建一个良好的动态查询,并在您的表格非常大的情况下更有效地获得结果。

无论如何,如果您有任何问题,请告诉我,希望这有帮助。

答案 2 :(得分:0)

Sri,根据要求,此解决方案使用动态查询。 但是,请记住,用户必须输入字段(或者您应该找出它们是什么,按照输入值的相同顺序在列表中构建它们)。此外,这不会针对任何字段过滤任何值,例如我之前发布的示例。所以这就是:

define temp-table ttTable
    field id as integer
    field state as character
    field city  as character
    field area  as character
    index idx is primary unique id.

DEFINE VARIABLE cFieldLst AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cKeyWords AS CHARACTER   NO-UNDO.
DEFINE VARIABLE i         AS INTEGER     NO-UNDO.
DEFINE VARIABLE hBuffer   AS HANDLE      NO-UNDO.
DEFINE VARIABLE hQuery    AS HANDLE      NO-UNDO.

DEFINE VARIABLE cStateLst AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cCityLst  AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cAreaLst  AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cQueryStr AS CHARACTER   NO-UNDO.
/* These variables are just to load the temp-table for the example */
cStateLst = 'Orissa,Orissa,Delhi,Delhi,Goa,Goa,Kerla,Kerla,Andhra,Andhra'.
cCityLst = 'Jaipur,Kuraput,Delhi,New Delhi,South Goa,Panaji,Chochin,Trivandram,Vizag,Hyderabad'.
cAreaLst = 'Town,Village,Town,Village,Village,Town,Town,Village,Town,Village'.
do i = 1 to 10:
   create ttTable.
   assign ttTable.id = i
          ttTable.state = entry(i,cStateLst)
          ttTable.city = entry(i,cCityLst)
          ttTable.area = entry(i,cAreaLst).
end.
/* For your real code, you don't need this loading part. */

update cFieldLst format "x(20)". 
/* Let's assume the user types the field names correctly */
/* and the same number and order of values for fields and filters */
/* for this example, let's use 'city,area' (again, no spaces) */

update cKeyWords format "x(20)".
/* now trim the comma separated list to avoid mismatches */
do  i = 1 to num-entries(cKeyWords):
    assign entry(i,cKeyWords) = trim(entry(i,cKeyWords)).
end.
/* trailing and leading spaces eliminated, let's begin */
assign hBuffer = temp-table ttTable:default-buffer-handle.

do i = 1 to num-entries(cFieldLst):
   assign cQueryStr = cQueryStr + (if cQueryStr <> '' then ' AND ' ELSE '') + 
                      entry(i,cFieldLst) + ' = ' + quoter(entry(i,cKeyWords)).
end.
/* this is what your where clause looks like. Remove this when not testing */
MESSAGE cQueryStr
    VIEW-AS ALERT-BOX INFO BUTTONS OK.

/* Creating dynamic query */
create query hQuery.
hQuery:set-buffers(hBuffer).
hQuery:query-prepare("FOR EACH ttTable NO-LOCK WHERE " + cQueryStr).
hQuery:query-open().
hQuery:get-first().
do  while not hQuery:query-off-end:
       display ttTable with frame f down.
       down with frame f.
    hQuery:get-next().
end.

再次,我希望这可以帮助你。

答案 3 :(得分:-1)

如果您只是想要数据库中有喀拉拉邦作为城镇的任何城市,那么您应该

for each table where city = "kerla" no-lock:
   display table.
end.
每个

检索多个记录,内部代码对每个记录执行一次。我不知道这对你有帮助,但我希望如此。