Como funciona a Keyword OF (em FINDs e FORs each)

Discussão em 'Progress 4GL' iniciado por joelscampos, Novembro 7, 2012.

  1. joelscampos

    joelscampos Membro Participativo

    Por favor, alguém tem uma explicação do funcionamento da keyword OF, que é utilizado em FIND e FOR (ex: FIND Customer OF Order NO-LOCK.)?

    Pelo que entendi lendo o manual e fazendo testes, a regra principal é: tem que haver ao menos um índice UNIQUE em qualquer uma das duas tabelas, e todos os campos desse índice unique devem existir na outra tabela.
    Fazendo testes vi as possibilidades são muitas e fica complicado chegar numa conclusão só nos testes.

    A dúvida que fiquei é a seguinte:
    dá para dizer "seguramente" que "sempre" que houver um índice UNIQUE numa das tabelas, e todos os campos desse índice existam na outra tabela, o relacionamento do OF será feito através dos campos deste índice UNIQUE? Simplesmente isso?
  2. baltazar

    baltazar Membro Participativo

    Não é necessário haver indice.

    O nome do campo tem que ser igual nas 2 tabelas.

    Tabela1

    cp_codigo
    trc_cod
    nome_cliente

    Tabela2

    dcc_coddoc
    dcc_ndoc
    trc_cod

    Se fizer o "OF" da Tabela 1 com a 2 tem "acesso" ao nome do cliente.

    Espero que tenha entendido.

    se fizer
  3. joelscampos

    joelscampos Membro Participativo

    Entendi.
    O que achei estranho e não entendi, é o motivo de dar erro de compilação no código:

    Código:
    DEF TEMP-TABLE tt1 NO-UNDO
        FIELD campo-a   AS INTEGER
        FIELD campo-b   AS INTEGER
        FIELD campo-c   AS INTEGER
        FIELD campo-d   AS INTEGER
        FIELD campo-e   AS INTEGER.
    
    DEF TEMP-TABLE tt2
        FIELD campo-a   AS INTEGER
        FIELD campo-x   AS INTEGER
        FIELD campo-z   AS INTEGER
        FIELD campo-y   AS INTEGER.
    
    
    FOR EACH tt1,
        EACH tt2 OF tt1:
        DISP tt2 WITH 1 COL WIDTH 300.
    END.
    
    Erro de compilação:
    "Index fields of table 1 must be fields in table 2. (230)"

    O campo "campo-a" existe nas duas tabelas e mesmo assim não funfa.
    Só para de dar erro depois que adiciono "INDEX idx1 IS UNIQUE campo-a" em qualquer uma das duas tabelas.
  4. baltazar

    baltazar Membro Participativo

    Não tenho a certeza, mas acho o conceito não se aplica quando são entre 2 TTs.

    Só quando é TT com Tabela "Real".
  5. lima

    lima Membro Participativo

    Faltou vc definir o indíce das 2 temp-table´s, sem a definição de indíce não funciona.

    o OF só funciona com indice e que tenha os mesmo nomes de campos.

    DEF TEMP-TABLE tt1 NO-UNDO
    FIELD campo-a AS INTEGER
    FIELD campo-b AS INTEGER
    FIELD campo-c AS INTEGER
    FIELD campo-d AS INTEGER
    FIELD campo-e AS INTEGER
    INDEX id AS PRIMARY UNIQUE campo-a.

    DEF TEMP-TABLE tt2
    FIELD campo-a AS INTEGER
    FIELD campo-x AS INTEGER
    FIELD campo-z AS INTEGER
    FIELD campo-y AS INTEGER
    INDEX teste AS PRIMARY UNIQUE campo-a.


    FOR EACH tt1,
    EACH tt2 OF tt1:
    DISP tt2 WITH 1 COL WIDTH 300.
    END.
  6. joelscampos

    joelscampos Membro Participativo

    O que baltazar falou parece ser a resposta: entre duas temp-tables o OF não funciona direito.


    Num programa grande, usei o OF para relacionar duas TTs, e deu erro durante a execução.
    Copiei partes do mesmo programa e montei um programa menor só para fazer teste, e o erro não aconteceu.

    A lógica do programa que apresentou erro é a mesma do exemplo abaixo, e durante a execução o Progress errou nesse trecho: "NOT CAN-FIND(FIRST tt2 OF tt1)".

    Código:
    DEF TEMP-TABLE tt1 NO-UNDO
        FIELD campo-a   AS INTEGER
        FIELD campo-b   AS INTEGER
        FIELD campo-c   AS INTEGER
        FIELD campo-d   AS INTEGER
        FIELD campo-e   AS INTEGER
        INDEX idx1 campo-a
                   campo-b
                   campo-c
        INDEX idx2 campo-d
                   campo-c.
    
    DEF TEMP-TABLE tt2
        FIELD campo-a   AS INTEGER
        FIELD campo-b   AS INTEGER
        FIELD campo-c   AS INTEGER
        FIELD campo-x   AS INTEGER
        FIELD campo-z   AS INTEGER
        FIELD campo-y   AS INTEGER
        INDEX idx1 IS UNIQUE  campo-a
                              campo-b
                              campo-c.
    
    /*valores duplicados na tt1*/
    CREATE tt1.
    ASSIGN tt1.campo-a = 1
           tt1.campo-b = 1
           tt1.campo-c = 1
           tt1.campo-d = 1
           tt1.campo-e = 1.
    
    CREATE tt1.
    ASSIGN tt1.campo-a = 1
           tt1.campo-b = 1
           tt1.campo-c = 1
           tt1.campo-d = 1
           tt1.campo-e = 1.
    
    
    
    FOR EACH tt1
        WHERE NOT CAN-FIND(FIRST tt2 OF tt1):
    
        CREATE tt2.
        BUFFER-COPY tt1 TO tt2.
    END.
    
    
    Fica a dica para não usar o OF entre TTs. :)

Compartilhe esta Página