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


Chamada de programa via Container

Olá!

Chamada de programas COBOL via Container.

A comunicação entre as rotinas/programas COBOL pode ser realizada de variadas formas, neste post será demonstrado como realizar a comunicação entre rotinas por meio de container.

A comunicação via container é realizada dentro de um canal de comunicação, e dentro deste canal é gravado os containers de requisição e de resposta.

Então, antes de requisitar a chamada da ROTINA-B é necessário que a ROTINA-A tenha gravado o container de requisição para a ROTINA-B. Assim, um dos primeiros processos que serão executados pela ROTINA-B é de recuperar o container de requisição, de modo que após todo o seu processamento será gravado no canal de comunicação um container com a resposta da execução da ROTINA-B, para que a ROTINA-A recupere este container.

A imagem abaixo demonstra um exemplo de cada processo (passo) que é executado, para haver comunicação via container.

Os passos numerados na imagem acima, são:

  1. É gravado um container de requisição para a rotina A.
  2. A rotina A recupera o container de requisição.
  3. Após processar os dados de entrada a rotina A grava um container de requisição para a rotina B.
  4. A rotina B recupera o container com os dados de entrada gravado pela rotina A.
  5. Se ocorrer ERRO no processamento da rotina B é gravado um container de erro, se não é executado o passo 6.
  6. Após todo o processamento da rotina B é gravado o container de resposta.
  7. Ao voltar a rotina A, está tenta recuperar um container de ERRO. De modo a verificar se ocorreu algum problema na execução da rotina B. Se não ocorreu nada é executado o passo 8.
  8. A rotina A recupera o container de resposta da rotina B.
  9. Grava um container de ERRO se acontecer um erro de processamento na rotina A, antes ou depois de requisitar outra rotina.
  10. Após todo o processamento da rotina A, é gravado um container de resposta.
  11. Quem requisitou a rotina A recupera a resposta da execução.
Os três comandos básicos para uma comunicação via container são: EXEC CICS PUT, LINK e GET.
  • Grava o container de dados no canal de comunicação:
EXEC CICS PUT
    CONTAINER ( 'NM-CTNR-*'                ) * Nome do container
    FROM      ( DADO-RPST-RTIN-*           ) * Nível 1 do grupo das variáveis
    FLENGTH   ( LENGTH OF DADO-RPST-RTIN-* ) * Nível 1 do grupo das variáveis
    RESP      ( CICS-RESP                  ) * Variável para o de código CICS
    RESP2     ( CICS-RESP2                 ) * Variável para o de código CICS
END-EXEC.

  • Realiza a chamada para a outra rotina.
EXEC CICS LINK
    PROGRAM ( 'ROTINA-B'  ) * Nome do container
    CHANNEL ( CANAL-ATUAL ) * Variável que armazena o canal de comunicação
    RESP    ( CICS-RESP   ) * Variável para o de código CICS
    RESP2   ( CICS-RESP2  ) * Variável para o de código CICS
END-EXEC.

  • Recupera o container de dados do canal de comunicação.
EXEC CICS GET
    CONTAINER ( 'NM-CTNR-*'                ) * Nome do container
    CHANNEL   ( CANAL-ATUAL                ) * Variável que armazena o canal de comunicação
    INTO      ( DADO-RQSC-RTIN-*           ) * Nível 1 do grupo das variáveis
    FLENGTH   ( LENGTH OF DADO-RQSC-RTIN-* ) * Nível 1 do grupo das variáveis
    RESP      ( CICS-RESP                  ) * Variável para o de código CICS
    RESP2     ( CICS-RESP2                 ) * Variável para o de código CICS
END-EXEC. 

No código de exemplo não foi utilizado o Delete container. Mas é uma boa pratica deletar o container que irá ser gravado, é uma forma de garantir que não terá sujeira no container a ser gravado no canal de comunicação.
A section para realizar o Delete container, é:

      *
      *----------------------------------------------------------------*
       950000-EXCR-CTNR-DADO-RPST       SECTION.
      *----------------------------------------------------------------*
      * -- DELETA O CONTAINER DE RESPOSTA SE ESTE EXISTIR
      *
           EXEC CICS DELETE
               CONTAINER   ( ‘nome-do-container' )
               CHANNEL     ( CANAL-ATUAL         )
               RESP        ( CICS-RESP           )
               RESP2       ( CICS-RESP2          )
           END-EXEC.
      *
           EVALUATE TRUE
               WHEN CICS-RESP = DFHRESP(CONTAINERERR)
               WHEN CICS-RESP = DFHRESP(NORMAL)
                   MOVE ZEROS           TO CICS-RESP
                                           CICS-RESP2
               WHEN OTHER
                   PERFORM 99900x-ERRO-0x
           END-EVALUATE.
      *
       950000-FIM.
           EXIT.
      *


Para não produzir uma página grande, neste post não adicionei os prints do código COBOL. Mas não se preocupe acesse os códigos da rotina A e da rotina B logo abaixo.

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

Até o próximo post!

terça-feira, 23 de fevereiro de 2016

MVC e COBOL

Olá!

Model - View – Controller (MVC)

Para o português: Visualização – Controles – Modelos

Muitos utilizam o padrão MVC para o desenvolvimento de seus sistemas de software, sendo que este padrão de desenvolvimento é composto por três camadas bem distintas e com características bem definidas, de modo que sistemas que são elaborados na linguagem COBOL também podem ser construídos sob este padrão.

Sendo também que algumas organizações usam este modelo, entretanto pode ser encontrado com outro nome, por exemplo as três camadas podem ser chamadas de:
  • Visualização – Negocial – Persistência
  • Apresentação – Controlador – Manter (CRUD)
Assim quando você se deparar com um modelo desenvolvimento de software em camadas, tenha atenção aos detalhes, pois você já pode estar trabalhando com MVC. Em uma pesquisa rápida na internet é possível encontrar variados artigos a respeito de MVC.

O significado de cada camada:

Modelos: as rotinas (programas) que estão nesta camada são responsáveis pelo CRUD (Criar, Consultar, Atualizar e Deletar) os dados no DB, ou seja, são aquelas rotinas que irão conter códigos COBOL e SQL.

Controles: é a camada responsável por controlar as informações do sistema, então de um modo simplificado está recebe as requisições da camada de Visualização (usuário), verifica o “que”, “quando”, “onde”, “como” deve ser processado os dados. De modo que os controles podem requisitar aos Modelos para realizar algumas operações do CRUD, ou simplesmente validar a requisição conforme as regras de negócio.

Visualização: essa camada mostrar as informações retornadas pelos Controles ao usuário final, de modo que é também por meio dessa camada que o usuário realiza alguma requisição ao sistema. Assim, não ocorre um processamento de dados nesta camada.

O fluxo de dados entre estas camadas é demonstrado de acordo a imagem abaixo:



Em algumas situações o Java pode requisitar um Modelo diretamente. Mas porquê? Imaginamos que o Java precise montar uma combo com os nomes dos professores e que já exista um modelo que realize a consulta no DB para retornar os nomes e matriculas dos professores, então não há necessidade de criar um Controle somente para repassar os dados para a Apresentação. Lembrando que em algumas organizações não é permitido a camada de visualização acesse diretamente os Modelos.

Assim em um sistema Java e COBOL, a camada de apresentação é de responsabilidade do Java, e os Controles e Modelos são do COBOL.

Então, os programas COBOL na camada de Controle deverão analisar a requisição do usuário e aplicar as regras de negócio para processar os dados que serão retornados da camada de Modelos, e por fim o Java irá somente organizar as informações recebidas do COBOL para uma melhor visualização da resposta ao usuário.

Algumas vantagens por utilizar MVC, são:
  • Facilita o reaproveitamento de código. Pois por exemplo suponhamos que se tenha que gerar três relatórios que as informações venham da mesma tabela e aplicando várias regras de negócio, assim será somente necessário a criação de um programa na camada de Modelo para pesquisas as informações e três controladores para aplicar as regras de negócio; 
  • Muitos sistemas estão sendo desenvolvidos sob este padrão; 
  • Facilidade para futuras manutenções do código, já que todo o código está bem separado e com suas características definidas; 
  • Quando bem testado uma parte do sistema/código já pode ser reaproveitado para as demais ações. 

Mas também existem algumas desvantagens, que são:
  • Maior nível de atenção aos detalhes do requisito para o desenvolvimento do sistema, de modo a separar as características dos programas; 
  • Como o código está bem separado, será necessário testa-lo parte a parte; 
  • Ter que pensar que todo o sistema será desenvolvido em MVC, não é uma tarefa simples.

Consultar a relação de Termos e Abreviaturas acesse 
aqui.

Até o próximo post!