Как я могу динамически изменить условия where для каждого l oop? - PullRequest
1 голос
/ 21 января 2020

У меня есть таблица записей, в которой есть два логических флага: holdn и holdl. Я хочу провести l oop через эту таблицу по 3 различным критериям.

Любой флаг имеет значение ИСТИНА - Мы хотим видеть все, что находится на удержании

Флаг удержания имеет значение ИСТИНА - Мы хотим видеть только те элементы, которые находятся на удержании по этой единственной причине

Флаг holdn равен TRUE. Мы хотим видеть только те элементы, которые приостановлены по этой другой причине.

Я не могу понять, как динамически изменять значения для каждого l oop на основании этого. До сих пор я пытался установить значение переменной на основе этих условий, а затем использовать содержимое переменной в качестве одного из параметров where. Это не работает, так как Progress жалуется на несоответствие данных. Переменная является строкой, флаги логичны, так что это имеет смысл. Смотрите пример кода ниже. Это фрагмент фактического кода с измененным именем таблицы. Переменные which-hold, order-from и др. c определены и установлены в другом модуле, который вызывает его.

DEFINE VARIABLE which-hold# AS CHARACTER FORMAT "x(30)" NO-UNDO.

CASE which-hold:
   WHEN "B" THEN which-hold# = "(widget.holdn or widget.holdl)".
   WHEN "L" THEN which-hold# = "widget.holdl".
   WHEN "N" THEN which-hold# = "widget.holdn".
END CASE.


for each widget where which-hold# and
         widget.order-no >= order-from and widget.order-no <= order-thru and
         widget.line-no >= line-from and widget.line-no <= line-thru and
         widget.joint-no >= joint-from and widget.joint-no <= joint-thru
         no-lock:

         A bunch of code to make a nice report with the retrieved records...

end.

Программист-самоучка, который унаследовал огромный, плохо документированный применение. Пожалуйста, будьте нежны.

Ответы [ 2 ]

3 голосов
/ 22 января 2020

Если вы предпочитаете не иметь дело с полудинамическими ручками, c также возможен подход:

define variable i as integer no-undo.

define query q for customer.

do while true:

  update i.

  case i:
    when 0 then quit.
    when 1 then open query q for each customer no-lock where custNum >= 1000.
    when 2 then open query q for each customer no-lock where state = "nh".
    otherwise   open query q for each customer no-lock where name begins "u".
  end.

  do while true with frame a:

    get next q.

    if not available customer then leave.

    display custNum name state with frame a 10 down.
    down with frame a.

  end.

  close query q.

end.
2 голосов
/ 22 января 2020

То, что вы хотите - это на самом деле динамический c запрос. Я вернусь к этому в конце, но сначала я хотел бы объяснить, почему вы не сможете попытаться подставить имя поля в переменную which-hold #: поскольку запрос оценивается во время компиляции. И это то, что он читает (предположим, что у которого-удержание # есть значение widget.holdn ДЛЯ КАЖДОГО виджета, где "widget-holdn" (...) И это не оценивается как ИСТИНА или ЛОЖЬ. Так что, спросите вы? Хорошо это ключ здесь. Каждое условие должно оцениваться как истинное или ложное, так что вам больше повезет, если вы попытаетесь

for each widget where (if widget-hold# = 'widget.holdn' then widget.holdn = true else TRUE) (...)

Опять же, обратите внимание, что условие будет существовать, если виджет-удерживать # имеет значение, которое я хочу, иначе оно вообще не фильтруется. Таким образом, вы можете просто кодировать, как я показал (для каждого из ваших условий), и оно должно работать нормально. НО позвольте мне предложить динамический c запрос вместо этого. Вам нужно иметь:

DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.

CREATE QUERY hQuery.
hQuery:SET-BUFFERS(BUFFER widget:HANDLE).
hQuery:QUERY-PREPARE('<THIS IS THE CORE>').
hQuery:QUERY-OPEN().
DO WHILE hQuery:GET-NEXT():
   A bunch of code to make a nice report with the retrieved records...  
END.

Таким образом, в ядре у вас есть строка, которая соответствует вашей для каждого, как вы хотите, чтобы он выглядел. Так должно быть, например (сохраните это в переменной или соберите его внутри запроса на подготовку, это не имеет значения):

'FOR EACH widget NO-LOCK WHERE ' + 
(if which-hold = 'B' then 'widget.holdn = true and widget.holdl = true'
 else if which-hold = 'L' then 'widget-holdl = true'
 else /* N */ 'widget-holdn = true').

Помните, я говорил, что ваш запрос оценивается во время компиляции? Ну, как вы знаете, динамические c запросы на другой конец оцениваются во время выполнения меня, так что будьте готовы к появлению ошибок только при запуске. Еще одна вещь, которую я должен упомянуть, - это динамические c запросы, которые медленнее, чем stati c, поэтому, пожалуйста, оцените и выберите свой яд:)

Это должно быть то, что вам нужно. Пожалуйста, дайте мне знать, если это будет полезно или у вас останутся какие-либо вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...