quinta-feira, 12 de maio de 2016

Mascaras de edição no COBOL

Olá!

Por meio do uso de mascaras de edição, é possível no COBOL a apresentar valores numéricos de formas variadas. Assim, neste post será demonstrado algumas dessas mascaras!

Primeiramente temos o valor 12732234 que será armazenado na variável GDA-NR-SMLC PIC  9(009), e posteriormente este valor será movimentado para as variáveis que estão definidas com a mascara.

As variáveis usadas para a demonstração do uso das mascaras de edição, são:
    * -- GUARDA O NUMERO PARA SIMULACAO DE APLICACAO DAS MASCARAS
       77 GDA-NR-SMLC                   PIC  9(009) VALUE ZEROS.
      *
      * -- GUARDA O NUMERO COM ZEROS A ESQUERDA E SINAL
       77 GDA-VL-COM-ZEROS              PIC  9(009) VALUE ZEROS.
      *
      * -- GUARDA O NUMERO SEM ZEROS A ESQUERDA E SINAL
      *    SOMENTE MOSTRA O SINAL QUANDO O NUMERO NEGATIVO
       77 GDA-VL-SEM-ZEROS              PIC --------9 VALUE ZEROS.
      *
      * -- GUARDA O NUMERO SEM ZEROS A ESQUERDA E SINAL
      *    MOSTRA O SINAL TAMBEM PARA OS NUMEROS POSITIVOS
       77 GDA-VL-SEM-ZEROS-SNL          PIC ++++++++9 VALUE ZEROS.
      *
      * -- GUARDA O NUMERO FORMATADO PARA A MASCARA DE DATA DD/MM/AAAA
       77 GDA-DATA                      PIC ZZ/ZZ/ZZZZ.
      *
      * -- GUARDA O NUMERO FORMATADO PARA O VALOR R$
       77 GDA-VALOR                     PIC -999.999,99.
      *
      * -- GUARDA O NUMERO FORMATADO PARA O VALOR R$ E SINAL
       77 GDA-VALOR-SNL                 PIC S9(09)V9(2).


Então, se executarmos um DISPLAY em cada variável, o formato que o valor 12732234 será apresentado, é:


  • DISPLAY GDA-VL-COM-ZEROS, apresenta: 012732234

Definição da variável: PIC 9(009)
Note que o valor 12732234 possui um "0" na frente. Pois, o valor é menor que o tamanho suportado por está variável, assim, as casas numéricas não usadas será apresentada com zero.



  • DISPLAY GDA-VL-SEM-ZEROS, apresenta: 12732234

Definição da variável: PIC --------9
Deste modo o valor não possui o zero na frente, e também não há sinalização. Sendo que se o valor fosse negativo, seria apresentado um sinal "-" de negativo para o valor.



  • DISPLAY GDA-VL-SEM-ZEROS-SNL, apresenta: +12732234

Definição da variável: PIC ++++++++9
Com essa mascara se o valor positivo será apresentado com o sinal "+" na frente do número. E se o valor negativo será apresentado com o sinal "-" na frente do número. De qualquer modo a sinalização do valor aparecerá.



  • DISPLAY GDA-DATA, apresenta: 12/73/2234

Definição da variável: PIC ZZ/ZZ/ZZZZ
Neste tipo de definição o valor será apresentado no formato de data DD/MM/AAAA.



  • DISPLAY GDA-VALOR, apresenta:  732.234,00

Definição da variável: PIC -999.999,99
Para apresentar o valor no formato de R$. Lembrando que com o uso de "-" na definição da variável somente aparecerá o sinal se o valor for negativo.



  • DISPLAY GDA-VALOR-SNL, apresenta:  +012732234.00

Definição da variável: PIC S9(09)V9(2)
Com está definição o valor será sinalizado para positivos e negativos, também apresentando os zeros a esquerda.


Como se trata de mascaras de edição, é uma boa pratica utiliza-las somente para a apresentação do valor final. Ou seja, não é comum usar variáveis definidas com algumas mascaras para realizar o processamento dos dados.

Para Ctrl + C dos códigos acesse aqui.
Consultar a relação de Termos e Abreviaturas acesse aqui.

Até o próximo post!

segunda-feira, 18 de abril de 2016

Chamada de programa via Commarea

Olá!

Em um post anterior (Chamada de programas COBOL via Container) apresentei uma das formas de realizar o trânsito de dados entre os programas COBOL com o uso de containers. Neste post será demonstrado a utilização de Commarea, que é mais uma forma de como os dados podem ser tramitados.

Sendo que uma das características que diferenciam a chamada via Container e Commarea, é o tamanho da informação que pode ser passada de um programa para o outro. Por exemplo, quando utilizamos Container é possível tramitar até 64.000k de bytes dentro de um container, e quando é feito via Commarea somente até 32.000k bytes. Para mais informações sobre a quantidade de dados suportados veja no post:
Quantidade de dados suportados Commarea / Container.

Assim, a idea básica, é que quando uma ROTINA-A chama a ROTINA-C via Commarea, é criado uma área comum que "conectar" as duas rotinas, de modo que essa área pode suportar até 32.000k bytes de informação.

Para melhor entender veja a imagem abaixo e a descrição de seus processos, que simulam a chamada da ROTINA-C para retornar o nome do aluno à ROTINA-A:

Fluxo de dados via Commarea

Os processos para o fluxo de dados para a imagem acima, são:

  1. A ROTINA-A realiza a chamada (CALL / LINK ) da ROTINA-C via Commarea, informando o código do aluno.
  2. Então a ROTINA-C recebe o código do aluno e faz seu processamento para retornar o nome do aluno.
  3. Assim a ROTINA-C preenche a variável NM-ALUNO na área comum com o nome do aluno referente ao código informado.
  4. De modo que a ROTINA-C devolve (GOBACK) o processamento para a ROTINA-A.
  5. Por fim, ao retornar a ROTINA-A a variável já está preenchida com o nome do aluno, assim está rotina continuará com o seu processamento.
E não necessariamente as duas rotinas precisam ser Commarea, pois como está sendo apresentado a chamada da ROTINA-C é feita via Commarea. Então, o programa que está sendo chamado (ROTINA-C) tem que ser Commarea, por outro lado o programa chamador (ROTINA-A) pode ser Commarea ou Container.

Então, para apresentar o respectivo processo da imagem acima, irei utilizar o mesmo código da ROTINA-A usado no post citado logo no inicio, só que com a incrementação do código para chamar a ROTINA-C.

O que defini as variáveis que comporão a área comum é o que está na Linkage Section da rotina que irá ser chamada (ROTINA-C). Sendo uma boa pratica que está área seja um BOOK, pois no programa chamador (ROTINA-A) deverá conter a mesma declaração de variáveis. Então, para facilitar cria-se um book que ambos programas deverão incluir.

Os comandos principais na ROTINA-A e ROTINA-C para esse tipo de chamada, são apresentados abaixo:

ROTINA-C
O book da ROTINA-C:
           03 REQUISICAO.
      * --    OBRIGATORIOS
               05 CD-ALUNO                       PIC  9(009) COMP.
      *
           03 RESPOSTA.
      * --    CONTROLE DE ERRO
               05 CD-ERRO                        PIC  9(009) COMP.
               05 TX-ERRO                        PIC  X(120).
      * --    DADOS PROCESSADOS

               05 NM-ALUNO                       PIC  X(050).

Sendo que o book acima será incluído logo na Linkage Section da ROTINA-C:
      *
      *----------------------------------------------------------------*
       LINKAGE                          SECTION.
      *----------------------------------------------------------------*
      * BOOK INCLUIDO DA ROTINA-C
       01 DFHCOMMAREA.
-INC BOOK-ROTINA-C

ROTINA-A
As alterações necessárias na ROTINA-A para realizar a chamada da ROTINA-C, são:

  • O include do book da ROTINA-C:

      * BOOK INCLUIDO DA ROTINA-C
       01 BOOK-DA-ROTINA-C.
-INC BOOK-ROTINA-C


  • O comando EXEC CICS LINK:

           EXEC CICS LINK
              PROGRAM  ( 'ROTINA-C'              )
              COMMAREA ( BOOK-ROTINA-C           )
              LENGTH   ( LENGTH OF BOOK-ROTINA-C )
              RESP     ( CICS-RESP               )
              RESP2    ( CICS-RESP2              )
           END-EXEC.

De modo que a ROTINA-C também pode ser chamada por meio de um comando CALL, e para não deixar uma página grande, este será demonstrado em outro post.

Para Ctrl + C dos códigos acesse aqui.
Consultar a relação de Termos e Abreviaturas acesse aqui.

Até o próximo post!

segunda-feira, 28 de março de 2016

Sql Codes

SQLCODE
SQLSTATE

Post em andamento. Sempre que possível é adicionado outros codes :-)

-119
SQLSTATE: 42803
A COLUMN OR EXPRESSION IN A HAVING CLAUSE IS NOT VALID

Possível solução:
1 - Verifique se TODOS os campos do Select estão no Group By. Exemplo:
       SELECT NOME,  SOBRENOME,  DATA,  ENDERECO FROM TABELA
     GROUP BY NOME,  SOBRENOME,  DATA,  ENDERECO





-304
SQLSTATE: 22003
A VALUE WITH DATA TYPE data-type1 CANNOT BE ASSIGNED TO A HOST VARIABLE BECAUSE THE VALUE IS NOT WITHIN THE RANGE OF THE HOST VARIABLE IN POSITION position-number WITH DATA TYPE data-type2

Possível solução:
1 - Verifique se as variáveis do COBOL estão na respectiva posição dos campos da tabela. Exemplo:
       SELECT NOME,  SOBRENOME,  DATA³,  ENDERECO FROM TABELA
        INTO :NOME, :SOBRENOME, :DATA³; :ENDERECO

2 - Verifique se as variáveis estão com tamanho e tipo correto.




-305
SQLSTATE: 22002
THE NULL VALUE CANNOT BE ASSIGNED TO OUTPUT HOST VARIABLE NUMBER position-number BECAUSE NO INDICATOR VARIABLE IS SPECIFIED

Possível solução: adicionar para os campos que podem ser nulos um indicador de nulidade.

Exemplo:
LOCAL-STORAGE
      * -- INDICADORES DE NULIDADE                                 
       77 IN-NULL-CAMPO-TRES            PIC S9(04) COMP VALUE ZEROS.
PROCEDURE DIVISION
              EXEC SQL                                               
               FETCH INSENSITIVE ABSOLUTE :POSICAO-CURSOR CURSOR-TESTE
                   INTO :CAMPO-UM
                      , :CAMPO-DOIS
                      , :CAMPO-TRES          :IN-NULL-CAMPO-TRES
             END-EXEC.




-420
SQLSTATE: 22018
THE VALUE OF A STRING ARGUMENT WAS NOT ACCEPTABLE TO THE function-name FUNCTION

Possível solução:
1 - Verifique se as variáveis do COBOL estão na respectiva posição dos campos da tabela, ou seja, se as variáveis do INTO estão na respectiva posição dos campos do SELECT. Exemplo:

SELECT NOME, SOBRENOME, DATA³, ENDERECO FROM TABELA
    INTO :NOME, :SOBRENOME, :DATA³; :ENDERECO

2 - Verifique se as variáveis estão com tamanho e tipo correto.

3 – Se tiver um campo varchar no Select para uma variável de item de grupo COBOL com tamanho (LEN) e texto, certifique que estão com o nível 49, exemplo:

01 TEXTO.
    49 TEXTO-LEN.                * -- armazena o tamanho do texto
    49 TEXTO-DESCRICAO. * -- armazena o texto




-504
SQLSTATE: 34000
IF THE CURSOR-NAME WAS <UNKNOWN>, THEN THE CURSOR WAS NOT SUCCESSFULLY DECLARED OR ALLOCATED.

Possível solução: O nome do cursor não foi "encontrado", então verifique se nas clausulas EXEC SQL que referenciam o cursor estão com o mesmo nome declarado ao cursor.




-530
SQLSTATE: 23503
THE INSERT OR UPDATE VALUE OF FOREIGN KEY constraint-name IS INVALID

Possível solução: Para realizar um Insert ou UpDate os valores das chaves estrangeiras devem existir no banco de dados, ou seja, os valores que estão sendo passados na instrução Insert ou UpDate devem ser valores válidos (existentes nas tabelas estrangeiras).




-803
SQLSTATE: 23505
AN INSERTED OR UPDATED VALUE IS INVALID BECAUSE THE INDEX IN INDEX SPACE indexspace-name CONSTRAINS COLUMNS OF THE TABLE SO NO TWO ROWS CAN CONTAIN DUPLICATE VALUES IN THOSE COLUMNS. RID OF EXISTING ROW IS X record-id

Possíveis soluções:
  1. No caso de ser tentativa de INSERT, verifique se os campos/valores (chave) já existem no banco de dados.
  2. Se for tentativa de UpDate ou Delete, verifique se há campos/valores (chave) duplicados.




-923
SQLSTATE: 57015
CONNECTION NOT ESTABLISHED: DB2 condition REASON reason-code, TYPE resource-type, NAME resource-name

Possível soluções:

  1. Verifique se o SQL está correto
  2. Tente executar o SQL por outra plataforma
  3. Certifique que o plano do Natural está correto