Попытка ЧТЕНИЯ ключа, размер которого превышает максимальный размер ключа файла

#universe #u2

Вопрос:

Я запускаю программу, которая помогает документировать то, что содержится в нашей базе данных 30-летней давности. В ходе этого процесса я получаю следующее сообщение об ошибке:

 Attempted READ of record ID larger than file/table maximum record ID size of 255 characters.
 

Моя программа работает так:

 LOOP WHILE I <= NUM.FILES
    RECORD          = ""
    FILENAME        = FILE.LIST<I>
    ERROR           = ""
    DEBUG.RECORD    = ""
    HAVE.LOOKED     = 0
    OPEN 'DICT ':FILENAME TO D.FILE THEN
        OPEN FILENAME TO T.FILE THEN
            STATEMENT   = "SSELECT ONLY DICT ":FILENAME:' BY FIELD.NO WITH FIELD.NO >= 0 AND WITH FIELD.NO <= 900 AND WITH FIELD # ".]"'
            DEBUG       = ""
            PRINT FILENAME
            EXECUTE STATEMENT RETURNING DEBUG
            LOOP WHILE READNEXT FIELDNAME DO
                READ FIELD.RECORD FROM D.FILE, FIELDNAME THEN
                    IF LEN(FIELDNAME) > BIGGEST.KEY.LEN THEN
                        BIGGEST.KEY         = FIELDNAME
                        BIGGEST.KEY.LEN     = LEN(FIELDNAME)
                        BIGGEST.KEY.FILE    = "DICT ": FILENAME
                        PRINT FILENAME:" ":LEN(FIELDNAME):" ":FIELDNAME
                    END
                    USE.COUNT           = ""
                    USE.LIST            = ""
                    USE.COUNT.STATEMENT = "SELECT ":FILENAME:" WITH ":FIELDNAME:' # ""'
                    DEBUGS              = ""
                    EXECUTE USE.COUNT.STATEMENT RTNLIST USE.LIST RETURNING DEBUGS
                    ROW         = ""
                    ROW<1,1>    = FIELD.RECORD<2>   ;   *Attribute Number
                    ROW<1,2>    = FIELDNAME         ;   *Field Name
                    ROW<1,3>    = FIELD.RECORD<1>   ;   *Field Type
                    ROW<1,4>    = FIELD.RECORD<10>  ;   *Field Size
                    ROW<1,5>    = FIELD.RECORD<12>  ;   *Is Multivalued: "" = no, "Y" = Multivalued, "###" = specific multivalue
                    ROW<1,6>    = FIELD.RECORD<13>  ;   *Is Subvalued: "" = no, "Y" = Subvalued, "###" = specific subvalue
                    ROW<1,7>    = FIELD.RECORD<7>   ;   *Automatic data output conversion
                    ROW<1,8>    = FIELD.RECORD<8>   ;   *Correlative field definition
                    ROW<1,9>    = FIELD.RECORD<11>  ;   *Field description
                    ROW<1,10>   = @SELECTED         ;   *Number of records that don't have this field blank
                    RECORD<-1>  = ROW
                    IF ROW<1,10> < 1 THEN
                        READ UNUSED.FIELDS FROM CHUCK.WORK, "FILE.DEBUG.UNUSED.FIELDS" ELSE
                            UNUSED.FIELDS = ""
                        END
                        UNUSED.FIELDS<-1> = FILENAME:VM:ROW
                        WRITE UNUSED.FIELDS ON CHUCK.WORK, "FILE.DEBUG.UNUSED.FIELDS"
                    END
                    IF FIELD.RECORD<2> = 0 AND @SELECTED > 0 AND HAVE.LOOKED = 0 THEN
                        LOOP WHILE READNEXT KEY FROM USE.LIST DO
                            IF LEN(KEY) > BIGGEST.KEY.LEN THEN
                                BIGGEST.KEY         = KEY
                                BIGGEST.KEY.LEN     = LEN(KEY)
                                BIGGEST.KEY.FILE    = FILENAME
                                PRINT FILENAME:" ":LEN(KEY):" ":KEY
                            END
                        REPEAT
                        HAVE.LOOKED = 1
                    END
                END
            REPEAT
        END ELSE
            ERROR<-1> = "Failed to open file '":FILENAME:"'"
        END
    END ELSE
        ERROR<-1> = "Failed to open file DICT '":FILENAME:"'"
    END
    WRITE RECORD ON CHUCK.WORK, "FILE.":FILENAME
    WRITE DEBUG.RECORD ON CHUCK.WORK, "FILE.DEBUG.":FILENAME
    READ CHUCK.LOG FROM CHUCK.WORK, "CHUCK.LOG" ELSE
        CHUCK.LOG = ""
    END
    CHUCK.LOG<-1> = "FILE '":FILENAME:"' had ":DCOUNT(RECORD,AM):" fields"
    IF ERROR THEN
        CHUCK.LOG<-1>   = ERROR
        ERRORS<-1>      = ERROR
    END
    WRITE CHUCK.LOG ON CHUCK.WORK,"CHUCK.LOG"
    CLEARSELECT
    I = I   1
REPEAT
 

Когда я просматриваю базу данных напрямую, я не могу найти никаких идентификаторов записей или ключей с более чем 35 символами в файле, что вызывает проблемы, и не более 70 символов во всей базе данных. Может ли кто-нибудь помочь определить, почему эти записи помечаются в этом процессе, но не могут быть обнаружены напрямую?

Ниже приведена программа, которую я написал специально для поиска проблемных записей, но она не может найти виновника

 OPEN "CHUCK.WORK" TO CHUCK.WORK ELSE
        PRINT "UNABLE TO OPEN CHUCK.WORK"
        RETURN
    END
    READ FILENAME FROM CHUCK.WORK, "LISTME" ELSE
        PRINT "UNABLE TO READ LISTME"
        RETURN
    END
    NUM.FILES = DCOUNT(FILENAME,AM)
    FOR I = 1 TO NUM.FILES
        OPEN FILENAME<I> TO T.FILE ELSE
            PRINT "UNABLE TO OPEN ":FILENAME<I>
            RETURN
        END
        EXECUTE 'SELECT ':FILENAME<I>
        LOOP WHILE READNEXT KEY DO
            IF LEN(KEY) > 20 THEN
                PRINT FILENAME<I>:" ":LEN(KEY):" ":KEY
            END
        REPEAT
    NEXT I
 

Обновить

Один из моих коллег определил источник проблемы, хотя мы еще не определили, как ее устранить: в одном из наших файлов есть многозначное поле, которое является ключом, используемым в коррелятиве. По какой-то причине Universe пытается прочитать весь атрибут, а не отдельное многозначное значение в качестве ключа, что приводит к длинным идентификаторам записей. Кто-нибудь может увидеть, делаю ли я что-то не так в своем коде или в базе данных есть какие-то настройки, которые нам нужно просмотреть?

Комментарии:

1. В dev самый длинный ключ составлял 69 символов в соответствии с приведенной здесь логикой

Ответ №1:

Когда вы видите эту ошибку, она не имеет никакого отношения к размеру ключей в файле, просто @ID, который вы пытаетесь ПРОЧИТАТЬ, длиннее 255 символов. Когда я это вижу, обычно показывайте мне, в какой строке исходного кода это произошло. Если вы поставите это прямо перед собой, вы сможете отследить эту строку.

 IF LEN(THIS.ID) GT 255 THEN
   DEBUG
END
 

Редактировать. По-видимому, ошибка в этом случае заключается в том, что номер строки не указан. Я не был уверен, было ли это опущено для ясности или было какой-то разницей во вкусе Вселенной, но теперь я считаю, что его отсутствие является намеком на то, что сообщение об ошибке исходит от оболочки, а не от интерпретатора.

 OPEN '','VOC' TO FILE.VOC ELSE STOP "CANNOT OPEN FILE VOC"
STMT = "SELECT VAL WITH ":STR("A",256):" EQ 0"
EXECUTE STMT RTNLIST USE.LIST RETURNING DEBUGS
CRT "**************************************"
READ TEST FROM FILE.VOC,STR("A",256) ELSE NULL
END
 

Который в моей системе выводит это.

 >RUN TEST.SC TEST.LONG.ID
Attempted READ of record ID larger than file/table maximum
record ID size of 255 characters.
RetrieVe: syntax error.  Unexpected sentence without filename.  Token was "".
          Scanned command was SELECT 'VAL' WITH 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' EQ '0'
**************************************
Program "TEST.LONG.ID": Line 5, Attempted READ of record ID larger than file/t
able maximum
record ID size of 255 characters.
>
 

Первый выглядит как ваше сообщение об ошибке и указывает на один из динамических операторов SELECT, которые вы создаете. @ID является синонимом с ключом записи, и, чтобы продолжить аналогию немного дальше, похоже, что вы пытаетесь разблокировать свой велосипед одним из этих комично больших «Ключей от города».

Комментарии:

1. Я думал, что поле @ID и ключ записи являются синонимичными понятиями. Кроме того, я не получаю номер строки в выводе ошибок.

2. Спасибо вам за то время, которое вы уделяете, чтобы помочь с этим. В соответствии с аналогией, однако, дело не в том, что я пытаюсь разблокировать свой велосипед ключом от города, а скорее в том, что я пытаюсь вставить весь свой брелок в замок сразу.