简体   繁体   English

UniQuery-如何在文件中查找字段的最大长度

[英]UniQuery - How to find the largest length of a field in a file

I'm trying to figure out how to find the largest length of records for a field in a file on a Unix-based Unidata database in a Manage2000 (M2k) MRP system. 我正在尝试找出如何在Manage2000(M2k)MRP系统中基于Unix的Unidata数据库上的文件中查找字段的最大记录长度。 I currently have the "Using Uniquery" and "Uniquery Command Reference" both for v7.2 and the closest that I have found is using "LIKE" and "UNLIKE", but it isn't working exactly like I was hoping. 我目前在v7.2上都具有“使用唯一性”和“ Uniquery命令参考”,而我发现最接近的是使用“ LIKE”和“ UNLIKE”,但是它的工作方式与我希望的不完全相同。

Basically, we have an QUOTES file with a "Part_Nbr" dictionary and I need to find the length of the largest "Part_Nbr" record in the file. 基本上,我们有一个带有“ Part_Nbr”字典的QUOTES文件,我需要在文件中找到最大的“ Part_Nbr”记录的长度。 The dictionary field maximum length is 19 characters. 词典字段的最大长度为19个字符。 In doing a random listing of records, I see some records have data length of 7 characters and some have 13 characters, but I need to find the largest data length. 在对记录进行随机列出时,我看到一些记录的数据长度为7个字符,而有些记录的数据长度为13个字符,但是我需要找到最大的数据长度。

Thanks in advance for your help and suggestions. 在此先感谢您的帮助和建议。

Best Regards, 最好的祝福,

--Ken -肯

First I will clarify some terms so that we are speaking the same language. 首先,我将澄清一些术语,以便我们说相同的语言。 You are appear to be using field and record interchangeably. 您似乎正在使用字段并互换记录。

A FILE (aka TABLE for SQL folk, 'QUOTES' in this case) contains 0 or more RECORDS . 一个FILE (在SQL中是TABLE,在这种情况下为'QUOTES')包含0个或多个RECORDS Each record is made up of multiple ATTRIBUTES (aka FIELD). 每个记录由多个属性 (也称为字段)组成。 You can reference these attributes using dictionary items (which can also create derived fields) 您可以使用字典项(也可以创建派生字段)引用这些属性。

In this case you want to find the longest length of data accessed via the Part_Nbr dictionary, correct? 在这种情况下,您想找到通过Part_Nbr词典访问的数据的最长长度,对吗?

Assuming this is correct, you can do it as follows 假设这是正确的,您可以按照以下步骤进行操作

Use a dictionary Item 使用字典项

Step 1: Create a I-type dictionary item (derived field). 步骤1:创建一个I型字典项(派生字段)。 Let us call it Part_Nbr_Len. 让我们将其称为Part_Nbr_Len。 You can do this at the command line using UNIENTRY DICT QUOTES Part_Nbr_Len as per the image below. 您可以按照以下图像在命令行使用UNIENTRY DICT QUOTES Part_Nbr_Len进行此操作。

在此处输入图片说明

  • Type = I (aka Derived Field) 类型= I (又名衍生字段)
  • LOC = LEN(Part_Nbr) (The field is the number of 1 byte characters in the Part_Nbr field) LOC = LEN(Part_Nbr) (该字段是Part_Nbr字段中1个字节字符的数量)
  • FORMAT = 5R (Right-aligned makes it treat this field as a number for sorting purposes) FORMAT = 5R (右对齐使其将此字段视为数字进行排序)
  • SM = S (This field is a single value) SM = S (此字段为单个值)

Step 2: List the file in descending order by Part_Nbr_Len and optionally as I have done, also list the actual Part_Nbr field. 第2步:按Part_Nbr_Len降序列出文件,并且可选地,如我所做的那样,还列出实际的Part_Nbr字段。 You do this by the following command. 您可以通过以下命令执行此操作。

LIST QUOTES BY.DSND Part_Nbr_Len Part_Nbr_Len Part_Nbr

在此处输入图片说明


Temporary command-line hack 临时命令行黑客

Alternatively, if you don't want something permanent, you could do a bit of a hack at the command line: 另外,如果您不想永久保留某些内容,则可以在命令行中进行一些修改:

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

在此处输入图片说明

Okay, let's break it down: 好吧,让我们分解一下:

  • list -> May or may not be important that this is lowercase. list ->小写可能不重要。 This enables you to use 'EVAL' regardless of your account flavor. 这样,无论您使用哪种帐户,都可以使用“ EVAL”。

  • EVAL -> Make a derived field on the fly EVAL ->快速生成派生字段

  • 10000+LEN(Part_Nbr) -> Sorting of derived field is done by ASCII order. 10000+LEN(Part_Nbr) ->派生字段的排序按ASCII顺序进行。 This means 9 would be listed before 15 when sorting by descending order. 这意味着当按降序排序时,将在15之前列出9。 The + 10000 is a hack that means ASCII order will be the same as numeric order for numbers between 0 and 9999 which should cover the possible range in your case + 10000是骇客,表示ASCII顺序与0到9999之间的数字的数字顺序相同,这应涵盖您所用的范围

  • EVAL "LEN(Part_Nbr)" -> Display the actual field length for you. EVAL "LEN(Part_Nbr)" ->为您显示实际字段长度。


EDIT 编辑

Solve via code for MultiValued lists 通过代码求解多值列表

If you have a MultiValued (and/or Sub-MultiValued) attribute, you will be required to use a subroutine to determine the length of the largest individual item. 如果具有MultiValued(和/或Sub-MultiValued)属性,则将需要使用子例程来确定最大单个项目的长度。 Fortunately, you can have a I-type dictionary item call a subroutine. 幸运的是,您可以让I型字典项调用子例程。

The first step will be to write, compile and catalog a simple UniBASIC subroutine to do the processing for you: 第一步将是编写,编译和分类一个简单的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

To compile a program it must be in a DIR type file. 要编译程序,它必须位于DIR类型的文件中。 As an example, if you have the code in the 'BP' file, you can compile it with this command: 例如,如果代码在“ BP”文件中,则可以使用以下命令对其进行编译:

BASIC BP SR.MV.MAXLEN

How you catalog it depends upon your needs. 如何分类取决于您的需求。 Their are 3 methods: 它们是3种方法:

  • DIRECT 直接
  • LOCAL -> My suggestion if you only want it in the current account 本地->如果您只想在当前帐户中使用我的建议
  • GLOBAL -> My suggestion if you want it to work across all accounts 全球->我的建议,如果您希望它适用于所有帐户

If you have the program compiled in the 'BP' file, the catalog commands for the above would be: 如果您在“ BP”文件中编译了程序,则上述目录命令将为:

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

After the subroutine has been cataloged, you will need to have the LOC field (attribute 2) of the dictionary item Part_Nbr_Len (as per first part of this answer) updated to call the subroutine and pass it the field to process: 对该子例程进行分类之后,您将需要更新字典项Part_Nbr_Len(根据该答案的第一部分)的LOC字段(属性2)以调用该子例程并将其传递给该字段进行处理:

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

Which gives you: 这给你:

在此处输入图片说明

This is a fantastic answer. 这是一个了不起的答案。 With more recent versions of Unidata there's a slightly easier, more efficient way to check for the longest MV field though. 但是,使用最新版本的Unidata可以更轻松,更有效地检查最长的MV字段。

If the DICT item becomes: 如果DICT项变为:

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

The basic program can become simpler and just find the MAXIMUM value of the multivalued list of lengths: 基本程序可以变得更简单,只需找到长度的多值列表的MAXIMUM值即可:

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

Too bad there's no '-MAXIMUMS' built in function to skip the basic program entirely! 太糟糕了,没有内置的“ -MAXIMUMS”功能可以完全跳过基本程序! It's worth reading section 5.9 of the UniQuery docs at: 值得阅读UniQuery文档的5.9节:

Rocket Software Uniquery Docs 火箭软件独特文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM