Histórico da Página
...
O programa deve ter variáveis para todas as colunas que desejar fazer entrada de dados na tela. Neste caso podemos declarar facilmente um RECORD que contenha todas as colunas da tabela LIVROS.
DATABASE livros DEFINE mr_livros LIKE livros.* FUNCTION menu() |
...
A função consultar, recebe o número do livro que se pretende procurar, procura-o no banco de dados, e mostra na entrada de dados todos os dados correspondentes. Note que o número do livro é introduzido na form.
FUNCTION consultar() INPUT BY NAME mr_livros.numero SELECT * IF status != 0 THEN |
Função que procura um livro com determinado número
A instrução CLEAR FORM serve para limpar todos os campos existentes na form corrente. No exemplo acima, se a busca for bem sucedida é feito um display de todas as colunas da tabela.
...
Esta função aceita os valores sem inicializar variáveis e sem limpar os campos da form, validando a existência de um livro válido.
FUNCTION
FUNCTION modificar() |
|
END FUNCTION |
Modificação de um livro
É feito um teste da variável mr_livros.numero para garantir que está preenchida com um número de livro existente.
...
Esta função exclui do banco de dados o livro correspondente aos dados presentes na entrada de dados.
FUNCTION
FUNCTION excluir() |
STOP IF sqlca.sqlcode <> 0 THEN |
END FUNCTION |
Exclusão de um livro
O teste da existência de livro corrente é feito da mesma forma que na função modificar.
As instruções INITIALIZE e CLEAR FORM aparecem para garantir a não existência do livro corrente após a sua exclusão quando bem sucedida.
10 Gestão de janelas – parte 2
...
A tecla de atalho para confirmação de uma instrução de entrada de dados (INPUT, DISPLAY ARRAY, INPUT ARRAY, PROMPT) antes que esta seja concluída normalmente, ou seja, podendo ser pressionada a qualquer momento, é a tecla ESC. A tecla ENTER é assumida como padrão para navegação entre campos e no caso do cursor estar posicionado no último campo pertencente a entrada de dados atual e o usuário pressionar ENTER, automaticamente a entrada de dados terá seus dados confirmados. Neste caso a variável INT_FLAG terá seu valor inalterado.
10.3 Exercício – novo campo e tratamento de tecla de interrupção
...
A form tem que possuir um novo campo onde será visualizado o nome da editora na seção SCREEN, assim:
EditoraEditora: [f009 ] [f9d ] |
Novo campo para visualização do nome de editora
Precisa também introduzir os atributos para este campo na seção ATTRIBUTES:
f9d f9d = FORMONLY.nome_editora TYPE LIKE editoras.nome, NOENTRY; |
Atributos do novo campo
O atributo FORMONLY identifica um campo com um nome permitindo dizer qual o tipo para esse campo. Neste caso definimos o tipo com LIKE , no entanto é possível definir o tipo através dos tipos elementares.
campo campo = FORMONLY.nome_do_campo [TYPE [tipo_de_dados | LIKE tabela.coluna]] |
Definição genérica do atributo FORMONLY
Utilizou-se também o atributo NOENTRY para forçar a instrução INPUT a não editar este campo, ou seja, para o comando INPUT este campo será somente para visualização.
O programa 4GL ainda não sabe como fazer a validação do código de editor. Para conseguir realizar esta função, utiliza-se a cláusula AFTER FIELD, faz-se uma consulta na tabela de editores e apresenta-se o nome do editor encontrado na tela.
DEFINE DEFINE l_nome_editora LIKE editoras.nome; AFTER FIELD editora END INPUT
|
END INPUT |
Alteração das instruções INPUT para efetuar as validações
Quando a variável SQLCA.SQLCODE indica a constante NOTFOUND, quer dizer que não foi encontrada a editora cujo código foi informado pelo usuário, sendo que neste caso é apresentada uma mensagem de erro e o cursor é retornado novamente para informar o mesmo campo até que o usuário informe um código de editora válido.
Para tratamento das teclas de interrupção ou confirmação, usando a variável INT_FLAG, de forma que a inclusão, modificação, consulta ou exclusão somente sejam efetivadas caso esta variável esteja com seu valor igual a 0 (FALSE), ou seja, se o usuário não pressionar a tecla de interrupção, deve-se implementar da seguinte forma:
DEFINE DEFINE l_nome_editora LIKE editora.nome; LET int_flag = 0
AFTER AFTER FIELD edicaoedição
AFTER AFTER INPUT END INPUT
END INPUT IF IF int_flag <> 0 THEN END IF
|
END IF |
Alteração das instruções INPUT para efetuar as validações
11 Interação do 4GL com o banco de dados
...
Uma instrução SELECT pode dar origem a mais de uma linha da dados (depende da cláusula WHERE).
errselecterrselect.4gl
MAIN MAIN SELECT numero, nome, edicaoedição END MAIN
END MAIN $ $ fglpc errselect.4gl |
Leitura com instrução SELECT que dá origem a mais do que uma linha.
Se consultar o manual de 4GL verificará que o erro aconteceu porque uma busca não devolveu exatamente uma linha.
...
Esta ação é realizada com o auxilio da instrução DECLARE associada a uma instrução SELECT.
...
DECLARE cq_livros CURSOR FOR
|
...
5 |
Abrir o cursor
Esta ação é realizada com a instrução OPEN, que provoca a execução da instrução SELECT associada ao cursor e a busca correspondente na base de dados é realizada nessa altura. A partir desta instrução até o cursor ser fechado fica associado um conjunto de linhas (conjunto ativo) que corresponde ao resultado da instrução SELECT. O cursor fica posicionado imediatamente antes da primeira linha.
...
OPEN cq_livroslivros
|
Acessar uma ou mais vezes ao cursor
Os acessos são feitos com o auxilio da instrução FETCH que avança a linha corrente para a linha seguinte e armazena os dados retornados desta linha nas variáveis definidas na cláusula INTO. Se o cursor estiver posicionado na ultima linha, a variável sqlca.sqlcode será atualizada com o valor NOTFOUND (ou código 100).
WHILE WHILE 1
|
WHILE |
Fechar o cursor
Ação realizada pela instrução CLOSE que faz a colocação do cursor em estado fechado.
Não é possível invocar uma outra instrução sobre o cursor que não esteja aberto. O cursor por estar fechado não deixa de ter uma instrução SELECT associada, que ao ser invocado pela instrução OPEN é executada novamente a instrução SELECT associado ao cursor.
...
CLOSE cq_livros livros |
Um cursor pode também ser fechado automaticamente através de uma instrução de fim de transação (COMMIT WORK ou ROLLBACK WORK), já que uma das ações destas instruções é fechar todos os cursores que se encontrarem abertos no momento. Mas isto somente ocorre se na instrução de definição do cursor (DECLARE) tiver sido omitido o atributo WITH HOLD.
Apresenta-se um exemplo de acesso a uma tabela do banco de dados por intermédio de um cursor.
cursor1.4gl DATABASE DATABASE livros
MAIN MAIN DECLARE cq_livros CURSOR WITH HOLD FOR
LET aux = 1 OPEN cq_livros
WHILE aux = 1
DISPLAY numero, nome
CLOSE cq_livros
$ fglpc cursor1.4gl |
Leitura dos livros com número < 5 usando um cursor
Quando se declara um cursor, pode-se definir a intenção de alterar os valores de algumas coluna das linhas lidas. Essa intenção define-se através da declaração "FOR UPDATE" após a instrução SELECT do cursor, como na figura a seguir.
...
DECLARE nome_cursor CURSOR FOR |
Definição genérica da declaração de um cursor FOR UPDATE
A alteração faz-se da seguinte forma:
- Declarar um cursor "FOR UPDATE"
DECLARE cq_livros CURSOR FOR
|
- Abrir o cursor da forma descrita anteriormente.
...
OPEN cq_livros livros |
- Posicionar o cursor na linha que se quer alterar:
FETCH cq_livros INTO ... |
Invocar a instrução UPDATE para alteração das colunas definidas na cláusula SET do registro corrente do cursor utilizando a cláusula CURRENT OF para indicar a atualização do registro correspondente a linha corrente do cursor.
UPDATE UPDATE SET <colunas a modificar>
|
Depois da instrução UPDATE o cursor continua posicionado na linha corrente.
...
cursupd.4gl DATABASE DATABASE livros DECLARE cq_livros CURSOR FOR
OPEN cq_livros
WHILE aux = 1
IF edicao IS NULL THEN
UPDATE livros PROMPT "Quer alterar mais livros (s/n):" IF sqlca.sqlcode != 0 THEN END WHILE END MAIN $ fglpc cursupd.4gl Artificial Artificial Inteligence using C -Qual a editora para este livro: BERTR |
Cursor para alteração ( FOR UPDATE )
11.1.1 Cursores com atributo SCROLL
...
Para evitar estes problemas usa-se os cursores com SCROLL (ou SCROLL cursor). O seu funcionamento é idêntico a um cursor normal sendo declarado, aberto, lido e fechado (DECLARE, OPEN, FETCH e CLOSE). A principal diferença entre os dois tipos de cursores está no fato dos cursores com SCROLL não poderem ser utilizados com a cláusula FOR UPDATE e na instrução FETCH o SCROLL cursor permite utilizar algumas palavras chaves que definem a forma de acesso desejada aos registros ativos num cursor aberto.
As formas de acesso são:
FETCH CURRENT | Registro corrente |
FETCH PREVIOUS | Registro anterior |
FETCH NEXT | Registro seguinte |
FETCH FIRST | Primeiro registro |
FETCH LAST | Último registro |
FETCH RELATIVE | Registro N a partir do registro corrente, respeitando o conjunto ativo do cursor. Quando N for positivo, indica N registros após o registro corrente e quando N for negativo, indica N registros antes do registro corrente |
FETCH ABSOLUTE | Elemento N do conjunto de registros ativo do cursor |
...
- Declarar um cursor associando-o a uma instrução INSERT.
DECLARE DECLARE cq_livros CURSOR FOR |
...
- Abrir o cursor. Identico a um cursor normal.
OPEN OPEN cq_livros
|
...
livros |
- Ler os dados para dentro de determinada variáveis (INPUT, LET).
...
- Escrever as variáveis no buffer com o auxilio da instrução PUT.
PUT PUT cq_livros livros |
- Fechar o cursor.
CLOSE CLOSE cq_livros livros |
O 4GL força a escrita do buffer no banco de dados sempre que o limite do buffer seja atingido ou o cursor seja fechado.
...
- Colocação de uma string com as instruções SQL desejadas dentro de uma variável tipo CHAR.
LET LET l_sql_delete = “DELETE FROM livros WHERE numero = 10”10” |
Instrução PREPARE
- Definição de um identificador de instrução a partir da string que contém a instrução. Esta tarefa e executada pela instrução PREPARE. Há validação da sintaxe da instrução contido na string.
PREPARE PREPARE var_delete FROM l_sql_delete delete |
Instrução PREPARE
- Execução da instrução através da instrução EXECUTE.
EXECUTE EXECUTE var_deletedelete |
Instrução EXECUTE
As instruções SQL enviadas ao PREPARE em tempo de execução não podem fazer referência a variáveis do 4GL, visto que nesta fase o programa já foi compilado.
...
- Preparar a instrução com PREPARE.
...
PREPARE id_expressão FROM expressão_charchar |
- Declarar o cursor para essa instrução.
DECLARE DECLARE nome_cursor CURSOR FOR id_expressãoexpressão
|
- Usar o cursor da mesma forma que se usa com instruções definidas antes da compilação. Se for usado o caracter '?' para substituir variáveis, é necessário usar a cláusula USING na abertura do cursor.
OPEN OPEN nome_cursor USING var1 var2 ... varn
|
varn |
11.3 Exercício – Otimização da função de consulta
A função de consulta foi inicialmente implementada de forma que utilizasse o comando INPUT seguido de um comando SELECT para pesquisa do registro no banco de dados.
...
A instrução CONSTRUCT edita a form corrente, e a partir dos dados que o usuário informa nas diversas colunas, constrói uma parte de uma instrução SELECT numa variável tipo CHAR que posteriormente pode ser preparada e executada. A variável CHAR preparada pela instrução CONSTRUCT pode ser utilizada como a cláusula WHERE de um SELECT, sem conter a palavra chave WHERE.
...
CONSTRUCT {BY NAME variavel_char ON lista_de_colunas [{BEFORE CONSTRUCT |
Definição genérica da instrução CONSTRUCT
Esta instrução em relação à cláusula BY NAME, funciona da mesma forma como na instrução INPUT, ou seja, se for utilizada não é necessário indicar o nome das variáveis internas relacionadas às forms a que se pretendem editar.
...
Para tratar este tipo de tela o 4GL possui as instruções DISPLAY ARRAY e INPUT ARRAY, associadas a novas definições nas forms.
DISPLAY ARRAY array_de_records TO array_da_tela.*
|
Definição genérica da instrução DISPLAY ARRAY
A instrução DISPLAY ARRAY envia um array de records do programa para a tela, por intermédio de um array de linhas na tela.
...