UniQuery - Как найти наибольшую длину поля в файле - PullRequest
1 голос
/ 21 сентября 2011

Я пытаюсь выяснить, как найти наибольшую длину записей для поля в файле в базе данных Unidata на основе Unix в системе MRP Manage2000 (M2k).В настоящее время у меня есть "Использование Uniquery" и "Справочник команд Uniquery" как для v7.2, так и самое близкое, что я нашел, это использование "LIKE" и "UNLIKE", но оно работает не совсем так, как я надеялся.

По сути, у нас есть файл QUOTES со словарем "Part_Nbr", и мне нужно найти длину самой большой записи "Part_Nbr" в этом файле.Максимальная длина поля словаря составляет 19 символов.Выполняя произвольный список записей, я вижу, что некоторые записи имеют длину данных 7 символов, а некоторые - 13 символов, но мне нужно найти наибольшую длину данных.

Заранее спасибо за вашу помощь и предложения.

С наилучшими пожеланиями,

- Кен

Ответы [ 2 ]

4 голосов
/ 21 сентября 2011

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

A FILE (он же TABLE для SQL folk, в данном случае «QUOTES») содержит 0 или более RECORDS ,Каждая запись состоит из нескольких АТРИБУТОВ (он же ПОЛЕ).Вы можете ссылаться на эти атрибуты, используя элементы словаря (которые также могут создавать производные поля)

В этом случае вы хотите найти самую длинную длину данных, доступ к которым осуществляется через словарь Part_Nbr, правильно?

Предполагая, что этоправильно, вы можете сделать это следующим образом

Использовать элемент словаря

Шаг 1: Создать элемент словаря типа I (производное поле).Давайте назовем это Part_Nbr_Len.Вы можете сделать это в командной строке, используя UNIENTRY DICT QUOTES Part_Nbr_Len, как показано на рисунке ниже.

enter image description here

  • Type = I (он же производное поле)
  • LOC = LEN (Part_Nbr) (поле представляет собой количество 1-байтовых символов в поле Part_Nbr)
  • FORMAT = 5R (справа-aligned заставляет его обрабатывать это поле как число для целей сортировки)
  • SM = S (это поле имеет одно значение)

Шаг2: Вывести список файлов в порядке убывания по Part_Nbr_Len и, по желанию, также перечислить фактическое поле Part_Nbr.Это можно сделать с помощью следующей команды.

LIST QUOTES BY.DSND Part_Nbr_Len Part_Nbr_Len Part_Nbr

enter image description here


Временный взлом командной строки

В качестве альтернативы, если выне хотите что-то постоянное, вы можете сделать небольшой взлом в командной строке:

list QUOTES BY.DSND EVAL "10000+LEN(Part_Nbr)" EVAL "LEN(Part_Nbr)" Part_Nbr

enter image description here

Хорошо, давайте разберемся с этим:

  • list -> Может или не имеет значения, что это строчные буквы.Это позволяет вам использовать «EVAL» независимо от вида вашего аккаунта.

  • EVAL -> Создать производное поле на лету

  • 10000+LEN(Part_Nbr) -> Сортировка производного поля производится в порядке ASCII.Это означает, что 9 будет указано до 15 при сортировке по убыванию.+ 10000 - это хак, означающий, что порядок ASCII будет таким же, как порядок чисел для чисел от 0 до 9999, который должен охватывать возможный диапазон в вашем случае

  • EVAL "LEN(Part_Nbr)" -> Дисплейфактическая длина поля для вас.


РЕДАКТИРОВАТЬ

Решить с помощью кода для многозначных списков

Если у вас естьатрибут MultiValued (и / или Sub-MultiValued), вам потребуется использовать подпрограмму для определения длины самого большого отдельного элемента.К счастью, вы можете иметь элемент словаря I-типа, вызывающий подпрограмму.

Первым шагом будет написать, скомпилировать и каталогизировать простую подпрограмму UniBASIC, чтобы выполнить обработку за вас:

SUBROUTINE SR.MV.MAXLEN(OUT.MAX.LEN, IN.DATA)

* OUT.MAX.LEN  : Returns the length of the longest MV/SMV value
* IN.ATTRIBUTE : The multivalued list to process

  OUT.MAX.LEN = 0
  IN.DATA = IN.DATA<1> ;* Sanity Check. Ensure only one attribute
  IF NOT(LEN(IN.DATA)) THEN RETURN ;* No Data to check

  LOOP
    REMOVE ELEMENT FROM IN.DATA SETTING DELIM
    IF LEN(ELEMENT) > OUT.MAX.LEN THEN OUT.MAX.LEN = LEN(ELEMENT)
  WHILE DELIM
  REPEAT

RETURN

Для компиляции программы она должна быть в файле типа DIR.Например, если у вас есть код в файле 'BP', вы можете скомпилировать его с помощью следующей команды:

BASIC BP SR.MV.MAXLEN

Способ его каталогизации зависит от ваших потребностей.Это 3 метода:

  • DIRECT
  • LOCAL -> Мое предложение, если вы хотите, чтобы оно было только в текущем аккаунте
  • GLOBAL -> Мое предложение, если вы хотите егодля работы со всеми учетными записями

Если у вас есть программа, скомпилированная в файле 'BP', команды каталога для вышеупомянутых команд будут:

  • CATALOG BP SR.MV.MAXLEN DIRECT
  • CATALOG BP SR.MV.MAXLEN LOCAL
  • CATALOG BP SR.MV.MAXLEN

После того, как подпрограмма была каталогизирована, вам потребуется поле LOC (атрибут 2) словарного элементаPart_Nbr_Len (согласно первой части этого ответа) обновлен для вызова подпрограммы и передачи ей поля для обработки:

SUBR("SR.MV.MAXLEN", Part_Nbr)

, что дает вам:

enter image description here

1 голос
/ 11 октября 2011

Это фантастический ответ.В более поздних версиях Unidata есть немного более простой и эффективный способ проверки самого длинного поля MV.

Если элемент DICT становится:

SUBR('-LENS', Part_Nbr);SUBR('SR.MV.MAXLEN',@1)

Основная программа может стать прощеи просто найдите МАКСИМАЛЬНОЕ значение многозначного списка длин:

SUBROUTINE SR.MV.MAXLEN(OUT.MAX.LEN, IN.DATA)
    OUT.MAX.LEN=MAXIMUM(IN.DATA)
RETURN

Жаль, что нет встроенной функции -MAXIMUMS, чтобы полностью пропустить основную программу!Стоит ознакомиться с разделом 5.9 документации по UniQuery по адресу:

Документация по Rocket Software Uniquery

...