sábado, 27 de agosto de 2016

Select de dois ou mais registros do DB - Cursor

Olá!

Após as postagens de apresentação do fluxo dos dados da utilização de uma instrução Select no COBOL, e também da declaração de um Cursor (as duas postagens anteriores). Temos, então, uma base para codificar um programa COBOL que retorne mais de um registro ao pesquisar informações no banco de dados (DB).

Para reforçar: quando pretendemos executar uma instrução SQL que retorne dois ou mais registros de uma consulta ao DB, é necessário utilizamos está instrução na declaração de um Cursor.

Assim, em código COBOL a ideia básica para utilizamos Cursor, é:
  • Abrir o Cursor
    • OPEN CURSOR - A abertura do cursor é o passo que executa a instrução SQL contida na declaração do Cursor. Ou seja, quando realizado o OPEN Cursor, o Select do mesmo é executado, assim gerando uma tabela temporária de resposta.
  • Ler a tabela temporária de resposta
    • FETCH CURSOR - Após a abertura do Cursor, temos os registros retornados da consulta na tabela temporária, e para ler/manipular os dados desta tabela executamos o comando Fetch no Cursor que ler o registro e movimenta os dados para as variáveis COBOL.
  • Fechar o Cursor
    • CLOSE CURSOR - Ao termino da leitura dos dados da tabela temporária fechamos o Cursor. Processo que encerrar o uso do Cursor, e limpa (apaga) a tabela temporária.

Abaixo é apresentado a tabela para a construção do código COBOL de exemplo:

PESSOA
CD_PESSOANOMESOBRENOMEIDADE
1FelipeBarbosa23
2AnaVieira20
3JoãoSantos19
4AlineSilva21
5MairaDantas25

O código de exemplo logo abaixo, tem como objetivo mostrar todos os nomes cadastrados na tabela PESSOA. Então, o código tem que consultar os nomes no campo NOME da tabela PESSOA, e apresentar (display) estes. Segue o código COBOL:

SELECT CURSOR - FELIPE BARBOSA FERREIRA
SELECT CURSOR - FELIPE BARBOSA FERREIRA
SELECT CURSOR - FELIPE BARBOSA FERREIRA
SELECT CURSOR - FELIPE BARBOSA FERREIRA

Assim, os pontos chaves do código, são:
  • LOCAL-STORAGE:
    • Declaração de variáveis para realizar o controle de leitura do Cursor, essas variáveis auxiliam a verificar se o Cursor está aberto, e se o processo de laço de repetição para leitura está no fim.
    • Declaração de variáveis para receber os dados da leitura do cursor.
    • Declaração do Cursor CURSOR-NOME com a instrução SQL para consultar os nomes.
    • Inclusão da biblioteca SQLCA (área de comunicação do SQL, mais informações clique aqui)
  • PROCEDURE DIVISION:
    • Section 10000-ABRE-CURSOR-NOME, que realiza a abertura (OPEN) do Cursor.
    • Section 20000-LER-CURSOR-NOME, responsável por realizar a leitura (FETCH) do Cursor (tabela temporária de resposta da execução do cursor).
    • Laço de repetição para mostrar o nome do registro lido, e ler o próximo registro do Cursor.
    • Section 300000-FECHA-CURSOR-NOME, encerra (CLOSE) o Cursor.
Note que neste código foi empregado todo assunto apresentado neste e nos dois posts anteriores.

Enfim, com este exemplo prático, foi formulado um código simples que contém os conceitos fundamentais para a execução de uma instrução Select que retorne como resultado mais de um registro do DB. De modo que de acordo com a necessidade este exemplo pode ser útil para criar um código mais elaborado.

Para Ctrl + C do código acesse aqui.
Consultar a relação de Termos e Abreviaturas acesse aqui.
FELIPE BARBOSA FERREIRA

Até o próximo post!



sábado, 20 de agosto de 2016

Declaração de Cursor

Olá!

Ao desenvolver um programa que consulte a base de dados (DB), e tenha mais de um registro como resultado da instrução Select, é necessário realizar a declaração de um Cursor para utilizar o SQL que realiza a seleção dos dados no DB.

A sintaxe da declaração de um cursor, é:

Sintaxe declaração cursor site IBM
Sintaxe declaração cursor - Site IBM
Os comandos que estão sublinhados em vermelho são de uso obrigatório, os demais são opcionais. Logo, os comandos básicos para declarar um cursor, são:

DECLARE CURSOR-NAME CURSOR FOR
SELECT-STATEMENT

Onde:
CURSOR-NAME: é o nome do cursor. Boa prática é nomear o Cursor com objetivo da consulta.
SELECT-STATEMENT: instrução Select.

Exemplo básico de um Cursor:
DECLARE LISTAR-NOMES CURSOR FOR
SELECT NOME
  FROM PESSOA
 WHERE CD_PESSOA > 0

Para esse exemplo de Cursor a leitura seria realizada com o comando Fetch da seguinte forma:
FETCH LISTAR-NOMES
INTO :GDA-NOME


  • INSENSITIVE SCROLL

Quando ocorre a necessidade de controlar a leitura dos registros retornados da instrução Select do Cursor, utilizamos o comando opcional INSENSITIVE SCROLL na declaração do Cursor, conforme:

DECLARE LISTAR-NOMES INSENSITIVE SCROLL CURSOR FOR
SELECT NOME
  FROM PESSOA
 WHERE CD_PESSOA > 0

De modo que para realizar a leitura dos registros deste Cursor, o comando Fetch deve possuir os seguintes comandos adicionais:

FETCH INSENSITIVE ABSOLUTE POSITION-READ CURSOR-NAME

Sendo que POSITION-READ é um valor numérico que indica a posição do registro que será lido pelo comando Fetch. Exemplo:

Tabela:
PESSOA
RegistroCD_PESSOANOMESOBRENOMEIDADE
1123FelipeBarbosa23
2212AnaVieira20
3354JoãoSantos19
4674AlineSilva21
5995MairaDantas25

Então, abaixo temos os passos principais em código COBOL para realizar a leitura dos registros da tabela acima:
* -- Variavel para armazenar a posição de leitura do cursor
77 POSICAO-REGISTRO                             PIC S9(009) COMP VALUE +0.

* -- Adiciona um para a posicao de leitura de registro
ADD 1 TO POSICAO-REGISTRO.

* -- Realiza a leitura do cursor na posição informada em posicao-registro
FETCH INSENSITIVE ABSOLUTE :POSICAO-REGISTRO LISTAR-NOMES
INTO :GDA-NOME

Então, se colocarmos as duas instruções de código acima (adição e leitura) em um loop que tenha a condição de executar enquanto POSICAO-REGISTRO < 5, o resultado seria:

Valor de POSICAO-REGISTROResultado (GDA-NOME)
1Felipe
2Ana
3João
4Aline


Caso o valor inicial de POSICAO-REGISTRO seja 3, a resposta apresentada seria:

Valor de POSICAO-REGISTROResultado (GDA-NOME)
1João
2Aline

Então, com a utilização do Insensitive Scroll na declaração do Cursor podemos realizar a paginação dos registros que são retornados da instrução SQL do Cursor. Pois, podemos construir uma lógica para controlar a quantidade de registros lidos do Cursor, e começar a ler novamente a partir da última posição lida.

Para maiores informações dos comandos contidos na declaração de um Cursor veja no site da IBM clique aqui.

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

Até o próximo post!

sexta-feira, 12 de agosto de 2016

SQL - Fluxo de dados Select / DB

Olá!

Quando é executado uma instrução Select que está em uma rotina COBOL para selecionar as informações que estão no banco de dados (DB), é importante ter em mente o fluxo que é realizado para que os dados sejam selecionados. Pois, para instruções avançadas de código, muito da otimização dessas depende de como os dados estão sendo processados.

Na imagem abaixo é apresentado o fluxo de dados, desde a requisição do usuário na camada de apresentação, até a resposta dos dados encontrados no DB. O inicio do fluxo de dados que ocorre entre as camadas de processamento está detalhado no post: 

Fluxo COBOL Select DB Felipe Barbosa Ferreira

O fluxo detalhado:
  1. O fluxo é iniciado a partir do momento que o usuário realiza uma requisição na camada de apresentação.
  2. Rotina-A da camada de controles realiza as regras negociais, e requisita a Rotina-B com o propósito de pesquisar os dados no banco de dados.
  3. Rotina-B executa a instrução SQL para consultar os dados no DB, nos passos:
    1. Executa a instrução Select;
    2. Se SQL executado com sucesso, é retornado uma tabela temporária com os registros encontrados;
    3. Para que o COBOL leia/transfira as informações que estão na tabela temporária para variáveis COBOL, é executado o comando Fetch para fazer a leitura de cada registro desta tabela e mover os dados para as variáveis COBOL.
  4. Após realizar a leitura de todos os registros, a Rotina-B envia a resposta da sua execução para a Rotina-A.
  5. Que por sua vez, a Rotina-A continua o seu processamento, e no final envia a sua resposta para a camada de apresentação.
Assim, no passo 3, nota-se que é onde todo o processamento para realizar uma consulta/leitura no DB é feito. Sendo que para o Select que retornar mais de um registro, é necessário a declaração de CURSOR, e também de uma lógica para realizar um laço de repetição (loop Fetch +1) com o objetivo de ler cada registro retornado da resposta do SQL.

Caso o SQL da rotina COBOL seja um Select simples que retorne apenas um registro (exemplo desta instrução foi apresentado no post: SQL - Select simples). A tabela de resposta irá conter apenas um registro, então, não sendo necessário a declaração de CURSOR e loop para leitura do resultado do SQL, conforme o código de exemplo do post citado.

Quando, não haver resposta para o Select executado, a tabela temporária será retornada vazia. Assim, quando realizado a leitura nesta tabela, será retornado que não há mais registros a serem lidos (SQLCODE +100).

Nos próximos posts será demonstrado a declaração de Cursor, e também o código COBOL com o Select que possui dois ou mais registros de repostas (Cursor), ou seja, o exemplo prático do fluxo de dados apresentado na imagem acima.

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

Até o próximo post!

quinta-feira, 4 de agosto de 2016

Convertendo String - Inspect Converting

Olá!

Para converte um ou vários caracteres de uma string para outro carácter, podemos utilizar o comando INSPECT CONVERTING.

A sintaxe básica desse comando é:

INSPECT string CONVERTING caracter-X  TO caracter-Y.

Exemplo:
INSPECT 'AAABCD' CONVERTING 'A' TO 'Z'.
Resultado:  ZZZBCD

Esse comando possui variadas cláusulas adicionas, conforme apresentado no código abaixo:

INSPECT CONVERTING FELIPE BARBOSA FERREIRA
INSPECT CONVERTING FELIPE BARBOSA FERREIRA


No código acima, temos três comandos de conversão, sendo o primeiro e segundo com o Inspect Converting, e o terceiro com o Inspect Replacing. De modo, que a execução dos comandos:

  1. Converte todas as letras para maiúsculo.
  2. Transforma as letras "ABORS" em "#", com a condição de converter apenas as letras que estão entre "Felipe" e "Ferreira".
  3. Troca todos os caracteres que estão após "Felipe" para "*".
O resultado da execução do código acima, é:
Nome em caixa alta: FELIPE BARBOSA FERREIRA
Resultado #: FELIPE ####### FERREIRA      
Resultado *: FELIPE ******************     

Para Ctrl + C do código acesse aqui.
Consultar a relação de Termos e Abreviaturas acesse aqui.
FELIPE BARBOSA FERREIRA

Até o próximo post!