Download - SQL Protheus

Transcript
Page 1: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Programação SQL (Avançado)

Com SigaAdvanced/ AP5

Banco de Dados Oracle é a marca registrada da Oracle Corporation.Banco de Dados MSSQL Server é a marca registrada da Microsoft.Banco de Dados Informix é a marca registrada da Informix Corporation.Banco de Dados Sybase é a marca registrada da Sybase Corporation.Banco de Dados UDB é a marca registrada da IBM.

Este material é de efeito didático/suporte e não pode ser reproduzido sem autorização da MicroSiga.

Page 2: SQL Protheus

Programação SQL com SIGA Advanced / AP5

CopyRight © 2000 Microsiga Software S.A.

Índice

1. Structure Query Language (SQL)1.1. Introdução1.2. SELECT1.3. Clausula WHERE1.4. INSERT1.5. UPDATE1.6. DELETE1.7. Funções de Agregação

1.7.1. SUM1.7.2. COUNT1.7.3. AVG1.7.4. MAX1.7.5. MIN1.7.6. Group By1.7.7. Clausula HAVING1.7.8. Clausula DISTINCT

1.8. Função de String ( SUBSTRING/SUBSTR )1.9. ORDER BY1.10. JOINS

1.10.1. INNER JOIN1.10.2. LEFT JOIN ou LEFT OUTER JOIN 1.10.3. RIGHT JOIN ou RIGHT OUTER JOIN 1.10.4. FULL JOIN ou FULL OUTER JOIN 1.10.5. CROSS JOIN

1.11. UNIONS1.12. SUB SELECTS1.13. TRIGGERS1.14. STORED PROCEDURES1.15. CURSORES

2. Programando SQL em RDMAKES 2.1. Query’s 2.2. Função ChangeQuery2.3. Stored Procedures2.4. Comandos DDL

2.4.1. Truncate Table2.4.2. Drop Table

Page 3: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Page 4: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3. Structure Query Language (SQL)3.1. Introdução

Neste capítulo iremos estudar as sintaxes básicas da linguagem SQL, mostraremos exemplos e executando exercícios práticos.

Você vai perceber que a linguagem SQL é sempre em comandos textos que são enviados ao servidor, este fará a compilação e execução da query. Este processo é feito a cada requisição ao servidor. Você perceberá que quanto menos solicitações melhor a performance obtida.

Existem vários comandos de manipulação do banco de dados como criação de tabela, índices, constraints, defaults, etc. Neste curso não estaremos comentando estes comandos, pois os mesmos dependem exclusivamente da plataforma e são de responsabilidade e conhecimento de um DBA. Indiretamente estas operações são executadas pelo TopConnect em comandos TC’s. Querendo utilizar uma destas funções, consulte o manual do banco de dados ou procure a orientação de um DBA.

Ferramentas de trabalho para os Banco de Dados mais comuns MSSQL Server (isql/w , Query Analyzer), Oracle (WorkSheet) e Informix (SQL Editor) . Estas ferramentas são muito similares a editores de texto, ou seja, você deve digitar todo o comando, e o mesmo será submetido imediatamente ao SGDB.

A seguir estaremos apresentando a sintaxe da linguagem SQL.

Page 5: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.2. SELECT

Este comando recupera informações gravadas no banco de dados. A diferença básica de um select para um programa orientado a registros é que em um select você pode recuperar várias linhas para uma determinada condição, ao contrário do programa que teria que efetuar vários acessos para obter o mesmo resultado.Ex. se você escrever um programa padrão ADVPL você terá que posicionar o registro, fazer um laço até o final do arquivo, lendo o próximo registro, etc. Veja agora como fazer em linguagem SQL.

Sintaxe:

SELECT [<apelido>.] <Nome da Coluna> [<Nome de Retorno>], n...FROM <Nome da Tabela> [<apelido>], n ...

<Nome da Coluna> => Informar o nome(s) da(s) coluna(s) da(s) tabela(s) que você deseja apresentar/manipular em seu aplicativo. Se você informar o símbolo ‘*’ (Asterisco) o comando assumirá todas as colunas da tabela.

<Nome da Tabela> => Informar o nome de todas as tabelas associadas ao resultado esperado. Se existirem colunas com mesmo nome em tabelas diferentes, você deverá associar o nome da tabela junto ao nome da coluna (SA1010.A1_NOME).

<Apelido> => sinônimo utilizado para referenciar uma tabela correspondente.

<Nome de Retorno> => Será o nome da coluna apresentado para sua aplicação como o nome original de resultado da query.

Ex. Select simples

SELECT * FROM SA1990

SELECT A1_COD, A1_NOME FROM SA1990

Quando utilizamos ‘*’ o SGDB estará retornando todas as colunas da tabela, recomendamos sempre informar as colunas que realmente você estará utilizando, por que, se a tabela possuir muitas colunas o tempo de resposta do seu select pode ser mais demorado.

Ex. Select com colunas compostas [ +, -, *, /, (, ) ]

SELECT C6_QTDVEN * C6_PRCVEN VALOR FROM SC6990

Para colunas do tipo numérico podemos fazer qualquer tipo de cálculo, lembrando que para o cálculo seräo considerados os operadores que estiverem dentro de parênteses para depois consideram os externos e assim por diante.Vale a pena lembrar que no banco de dados os campos numéricos säo do tipo float, portanto näo possuem limitaçäo de casas decimais. No momento de utilizar o resultado devemos efetuar o arredondamento dos dados com a funçäo abaixo:

Sintaxe: ROUND(Coluna,Precisão)

Page 6: SQL Protheus

Programação SQL com SIGA Advanced / AP5

SELECT round(round(C6_QTDVEN,4)*round(C6_PRCVEN,2),2)VALOR FROM SC6990

Ex. Select com uso de apelido nas colunas

SELECT A1_COD CODIGO, A1_NOME NOME, R_E_C_N_O_ RECNO FROM SA1990

Neste caso percebemos que na frente de cada nome de coluna existe um outro nome referenciando a respectiva tabela que chamamos de apelido. Este nome será utilizado como referência na resposta da query.

Ex. Select com uso de apelido nas tabelas

SELECT SA1.A1_COD, SA1.A1_NOME FROM SA1990 SA1

SELECT SA1.A1_COD CODIGO, SA1.A1_NOME NOME, SC5.C5_NUM NUM FROM SA1990 SA1, SC5990 SC5

Agora temos um exemplo de utilização de mais de uma tabela, para referenciarmos a vários campos

Ex. Select com uso de múltiplas tabelas com seleção de todas as colunas de uma tabela, e apenas algumas de outra tabela

SELECT SA1.*, SC5.C5_NUM NUM FROM SA1990 SA1, SC5990 SC5

Ex. Select com concatenação de colunas

SELECT A1_COD + A1_LOJA CODIGO FROM SA1990

Obs: Para Banco de dados Oracle e Informix utilize dois pipes ‘|’ no lugar de ‘+’.

3.3. Clausula WHERE

Esta clausula é uma das mais importantes do comando SELECT, pois é a partir dela que filtramos os dados da query. O filtro que estaremos informando é muito parecido com a que utilizamos em uma função indregua(), em ADVPL.

Sintaxe:

SELECT [<apelido>.] <Nome da Coluna> [<Nome de Retorno>], n...FROM <Nome da Tabela> [<apelido>], n ...WHERE <Condição de filtro>

<Condição de filtro> - informar uma expressão lógica que estará eliminando as linhas que estiverem dentro do contexto informado.

Dentro da condição de filtro você pode utilizar os seguintes operadores :

Page 7: SQL Protheus

Programação SQL com SIGA Advanced / AP5

= (igualdade) > (maior que) < (menor que) >= (maior que ou igual a) <= (menor que ou igual a) <> (diferente) != (diferente) (não é SQL-92 padrão). !< (Não menor a) (não é SQL-92 padrão). !> (Não maior a) (não é SQL-92 padrão).AND Verdadeiro se ambas expressões forem verdadeirasOR Verdadeiro se qualquer expressão for verdadeiraBETWEEN Verdadeiro se a expressão esta dentro de um

determinado intervaloEXISTS Verdadeiro se uma subquery contém alguma linhaIN Verdadeiro se o operando é igual a uma das

expressões da listaNOT Inverte o valor de qualquer outra expressão boleanaLIKE ([ _ ],%) Verdadeiro se a expressão fixa for encontrada.

Ex. Select utilizando alguns dos operadores

SELECT * FROM SE1990WHERE E1_FILIAL = '01'

AND E1_CLIENTE BETWEEN ' ' AND 'zzzzzz' AND E1_LOJA BETWEEN ' ' AND 'zz'

AND E1_PREFIXO LIKE 'P%' AND E1_NUM BETWEEN ' ' AND 'zzzzzz' AND E1_VENCREA BETWEEN '20000225' AND '20001231' AND E1_EMISSAO <= '20001231' AND E1_TIPO IN ('DP ','NF ','AB-','NCC','NCD') AND NOT E1_EMISSAO = '20000401' AND D_E_L_E_T_ <> '*'

Nota: A clausula where deve sempre compor o máximo possível de campos que se adequam a uma chave de índice e o máximo de filtro possível definido, desta forma as suas query’s terão sempre um resposta rápida.

Page 8: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.4. INSERT

Este comando insere uma linha em uma tabela ou visão. A inserção feita pelo SigaAdvanced/AP5 se utiliza deste comando. Em um programa ADVPL não é necessário a utilização deste comando, pois o TopConnect efetua uma série de controles na operação.

Sintaxe:

INSERT INTO <Nome da Tabela> | <Nome da Visão> [ ( Coluna 1,Coluna n,... )

VALUES ] ( Conteúdo_coluna1, Conteúdo_coluna n,...)

Ex. Insert completo

INSERT INTO SA4990 (A4_FILIAL,A4_COD,A4_NOME,A4_NREDUZ,A4_VIA,A4_EST, A4_CGC,A4_TEL,R_E_C_N_O_)

VALUES (' ','000001','TRANSP.AREO', 'STAR', 'AEREA', 'SP', '51706778000151','765-7865',1)

Ex. Insert informando só o conteúdo a inserir

INSERT INTO SA4990 (' ','000001','TRANSP.AREO', 'STAR', 'AEREA',

'SP', '51706778000151','765-7865',1)

Ex. Insert com select e numeração automática da coluna R_E_C_N_O_

INSERT INTO SA4990 SELECT ' ','000001','TRANSP.AREO','STAR',

'AEREA','SP', '51706778000151','765-7865', isNull(max(R_E_C_N_O_),0) + 1

FROM SA4990

Obs: função isnull é do MSSQL Server, para Oracle utilize nvl

Nota: Recomendamos sempre informar o nome das colunas que estarão sendo inseridas, pois se optar pela omissão dos nomes, os valores deverão ser informados na ordem de criação da tabela.

Page 9: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.5. UPDATE

Comando para fazer alterações nas informações gravadas. Estas alterações podem ser processadas linha a linha ou em bloco, de acordo com a condição de filtro informada.

Sintaxe:

UPDATE [FROM] <Nome da Tabela> SET <Nome da Coluna> = <expressão> | <valor>

WHERE <Condicional de Filtro>

Lembre-se que o comando update faz controle transacional implícito, ou seja, enquanto o comando não for executado até o seu final com sucesso o dado não estará confirmado (Commit). Para a execução do comando o banco utilizará área de log, portanto se formos executar um update cujo filtro atinja toda a tabela, será necessário espaço suficiente para alocar a transação na área de log.

Ex. Update padrão utilizado pelo SigaAdvanced / AP5

UPDATE SA4990 SET A4_NOME = ‘TRANSPORTADORA STAR LTDA’

WHERE R_E_C_N_O_ = 10

Neste exemplo será alterado apenas as linhas que tenham Recno igual a 10, como o recno é chave única da tabela apenas um registro será alterado.

Ex. Update com condicional diferente

UPDATE SA4990 SET A4_NOME = 'TRANSPORTADORA STAR LTDA' WHERE A4_COD = '000001' AND D_E_L_E_T_ <> '*'

Neste caso a alteração será feita em todas as linhas que possuem a coluna A4_COD = '000001' e a coluna D_E_L_E_T_ diferente de '*'.

Ex. Update com campos de cálculo

UPDATE SB1990 SET B1_PRV1 = B1_PRV1 + ( (B1_PRV1 + 10) / 100 ) WHERE D_E_L_E_T_ <> '*'

Neste exemplo o registro será alterado com o resultado do cálculo.

Ex. Update padrão de exclusão de registro do SigaAdvanced / AP5

UPDATE SA4990 SET D_E_L_E_T_ = ‘*’

WHERE R_E_C_N_O_ = 10

Neste exemplo o registro é excluído para o sistema SigaAdvanced, ou seja, através da programação em ADVPL o comando delet() estará executando o update acima, fazendo uma marca no registro, pois a exclusão é lógica.

Alerta: Nunca execute um comando update sem um condicional, desta forma você estará alterando todos as linhas da tabela e também estará correndo o risco de estourar a área de log do Banco de Dados. (Utilize ferramentas como SDU ou Configurador)

Page 10: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.6. DELETE

Comando para efetuar a exclusão física da informação. No SigaAdvanced / AP5 apenas o comando pack executa esta instrução. A construção deste comando é semelhante ao update, possuindo também opção de filtro.

Sintaxe:

DELETE [FROM] <Nome da Tabela> WHERE <Condicional de Filtro>

Lembre-se que o comando delete faz controle transacional implícito, ou seja, enquanto o comando não for executado até o seu final com sucesso o dado não estará confirmado (Commit). Para a execução do comando o banco utilizará área de log, portanto se formos executar um delete cujo filtro atinja toda a tabela, será necessário espaço suficiente para alocar a transação na área de log.

Ex. Delete para exclusão física de uma linha

DELETE SA4990WHERE R_E_C_N_O_ = 10

Neste exemplo será excluído apenas as linhas que tenham Recno igual a 10, como o recno é chave única da tabela apenas um registro será alterado.

Ex. Delete com condicional diferente

DELETE SA4990 WHERE A4_COD = '000001' AND D_E_L_E_T_ = '*'

Neste caso a exclusão será feita em todas as linhas que possuem a coluna A4_COD = '000001' e a coluna D_E_L_E_T_ igual a '*'.

Note: Em alguns Bancos de Dados você pode utilizar o comando TRUNCATE TABLE, que estará fazendo o mesmo que um comando ZAP em ADVPL. Só que esta operação é extremamente rápida, para conhecedores de Cobol, esta operaçào é conhecida como OPEN OUTPUT. Atenção depois desta operação não existe mais como recuperar as linhas da tabela. (Esta operação não utiliza LOG).

Alerta: Nunca execute um comando delete sem um condicional, desta forma você estará excluindo todos as linhas da tabela e também estará correndo o risco de estourar a área de log do Banco de Dados.

Page 11: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.7. Funções de Agregação

O objetivo principal das funções de agregação é criar colunas de acumuladores de um determinado agrupamento definido pela cláusula group by. Se esta cláusula não for informada o retorno será sempre uma linha.

Sintaxe genérica para as funções:

SELECT [DISTINCT] [<FUNCAO>( ] <Nome da coluna|*>[)][ WHERE <Condicional de Filtro por linha> ][ GROUP BY <Colunas de agrupamento, coluna1, …, coluna16> ][ HAVING <Condição de agrupamento> ]

3.7.1. SUM

Esta função retorna a somatória de uma coluna(s) defina pelo usuário.

Ex. Select que retorna o total de saldo de duplicatas de clientes

SELECT SUM(A1_SALDUP) FROM SA1990WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o saldo total dos títulos em aberto eliminando os registros excluídos da base de dados.

3.7.2. COUNT

Esta função totaliza o número de linhas na tabela, utlizando filtro para tal. Se for informado o nome de uma coluna, a função contará apenas as linhas que não estiverem com seu conteúdo nulo.. Ex. Select que retorna o total de linhas da tabela

SELECT COUNT(*) FROM SA1990WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o total de linhas não excluídas.

Ex. Select que retorna o total de linhas da tabela, considerando somente uma coluna

SELECT COUNT(A1_FILIAL) FROM SA1990WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o total de linhas não excluídas. Se houver conteúdo nulo em alguma linha, esta não será contada.

Page 12: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.7.3. AVG

Esta função retorna a média aritmética da coluna informada, filtrando as linhas pela clausula where ou having.

Ex. Select para média do saldo a receber de cada cliente

SELECT AVG(A1_SALDUP) FROM SA1990WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna a média da coluna A1_SALDUP, não considerando as linhas excluídas.

3.7.4. MAX

Esta função retorna o valor máximo da coluna especificada.

Ex. Select para o maior valor da coluna R_E_C_N_O_

SELECT MAX(R_E_C_N_O_) FROM SA1990

Este exemplo retornará o maior valor da coluna, o mesmo é muito usado para se saber qual a próxima seqüência disponível. Nunca despreze as linhas excluídas, por que este número é sequencial e único na tabela.

3.7.5. MIN

Esta função retorna o valor mínimo da coluna especificada.

Ex. Select do menor valor da data de emissão do pedido

SELECT MIN(C6_EMISSAO) FROM SC6990 WHERE C6_CLI = ‘ 123456’ AND D_E_L_E_T_ <> ‘*’

Este exemplo retorna o menor valor da coluna C6_EMISSAO.

3.7.6. GROUP BY

Esta cláusula define quais colunas determinam o agrupamento do comando select.

Ex. Select para obter valor total de pedidos por cliente e data

SELECT C6_CLI, C6_LOJA, C6_EMISSAO, SUM(C6_VALOR) TOTAL FROM SC6990 WHERE D_E_L_E_T_ <> ‘*’ GROUP BY C6_CLI, C6_LOJA, C6_EMISSAO

Este exemplo faz a somatória da coluna C6_VALOR, efetuando o agrupamento do resultado por cliente, loja e data.

Page 13: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Ex. Select para obter quantidade de pedidos por cliente

SELECT C6_CLI, C6_LOJA, COUNT(*) QTD_PED FROM SC6990 WHERE D_E_L_E_T_ <> ‘*’ AND C6_EMISSAO between ‘19990101’ and ‘19990630’ GROUP BY C6_CLI, C6_LOJA

Este exemplo retorna a quantidade de pedidos, agrupando o resultado por cliente e loja, filtrando o resultado por data de emissão.

3.7.7. HAVING

Esta cláusula tem por finalidade filtrar os dados que estão numa condição de agrupamento. Apesar de ser uma cláusula de filtro (semelhante à cláusula where), ela é dependente da cláusula group by.

Ex. Select para obter códigos inseridos com duplicidade

SELECT A1_COD, A1_LOJA, COUNT(*) FROM SA1990 WHERE D_E_L_E_T_ <> ‘*’ GROUP BY A1_COD, A1_LOJAHAVING COUNT(*) > 1

Este exemplo faz a contagem do número de ocorrências de código e loja em duplicidade. A clausula having elimina as ocorrências não duplicadas, ou seja count(*) <= 1.

3.7.8. DISTINCT

Esta cláusula elimina repetições para a coluna informada.

Ex. Select para obter todos os CFOs utilizados pelo cliente

SELECT DISTINCT F4_CF FROM SF4990 WHERE D_E_L_E_T_ <> ‘*’

Este exemplo elimina do resultado os CFO’s repetidos.

Ex. Select para obter código das filiais com linhas existentes (válido para tabela com X2_MODO = ‘E’)

SELECT DISTINCT A1_FILIAL FROM SA1990 WHERE D_E_L_E_T_ <> ‘*’

Page 14: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.8. Função de String ( SUBSTRING/SUBSTR )

Esta função é idêntica a função SUBSTR usada em ADVPL, e pode ser utilizada em qualquer ponto do select onde informamos uma coluna.

OBS: Para MSSQL Server e Sybase a sintaxe é SUBSTRING. Em Oracle e Informix a sintaxe é SUBSTR.

Sintaxe genérica para as funções:

SUBSTR[ING](<Origem>,<n posição inicial>,<tamanho em bytes>)

Ex. Select para apresentar parte do nome do cliente para todos os clientes que possuem ‘5’ na segunda posição do código.

SELECT SUBSTRING(A1_NOME,1,20) NOME FROM SA1990 WHERE SUBSTRING(A1_CODIGO,2,1) = ‘5’ AND D_E_L_E_T_ <> ‘*’

Não recomendamos a utilização da função na cláusula WHERE, pois o banco terá que fazer uma busca em toda a tabela, por não possuir índice do conteúdo a ser filtrado.

3.9. ORDER BY

Esta cláusula ordena o resultado do select independente do índice utilizado para acessar o dado. O resultado pode ser ordenado de forma crescente(ASC) ou decrescente (DESC). Um detalhe importante para performance do comando é tentar utilizar na cláusua ORDER BY as mesmas colunas que compõe um índice já existente no banco de dados, caso contrário o banco terá que ordernar os dados na área temporária (TempDB) o que pode prejudicar a performance do comando.

Sintaxe :

SELECT …FROM …ORDER BY <Coluna1> [ASC|DESC],…,<Coluna16> [ASC|DESC]

Ex. Select para apresentar o nome de todos os clientes por ordem decrescente de nome.

SELECT A1_NOME FROM SA1990 WHERE D_E_L_E_T_ <> ‘*’ ORDER BY A1_NOME DESC

Ex. Select para apresentar os cliente por ordem de código e loja de forma crescente.

SELECT A1_COD, A1_LOJA FROM SA1990 WHERE D_E_L_E_T_ <> ‘*’ ORDER BY A1_COD, A1_LOJA

Page 15: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Note que neste exemplo não é necessário informar a expressão ASC, para obter o resultado de forma crescente.

Nota : Em alguns casos de query´s você irá perceber que o resultado já estará apresentando as linhas por uma certa ordenação, isto que dizer que o banco de dados utilizou um índice para resolver o problema, mas isto não indica que sempre o dado será retornado nesta ordem, portanto se você precisar que o dados retornados estejam ordenados você dever sempre informa o ORDER BY.

3.10. JOINS

Esta operação é uma das mais poderosas expressões de um comando select, pois com ela podemos relacionar tabelas obtendo informações cruzadas. Este comando pode ser escrito de duas formas, porém alguns bancos suportam apenas uma delas. Estaremos apresentado esta forma e comentaremos suas diferenças.

O relacionamento entre as tabelas é feito utilizando o símbolo de igualdade entre duas colunas, sendo uma coluna de cada tabela. Lembre-se que o relacionamento é feito de forma binária, ou seja, só podemos relacionar duas tabelas de cada vez, mas podemos com isto relacionar quantas tabelas desejarmos, limitado pela capacidade do banco de dados.

Como recomendação devemos sempre tentar relacionar no máximo quatro tabelas, lógico que existe exceções, mas sempre que houver o relacionamento de muitas tabelas o banco de dados precisará de mais tempo para conseguir resolver o problema e em alguns caso não será viável. Existem várias situações que dependem de experiência e teste para conseguirmos chegar na melhor solução possível.

Sempre que utilizarmos joins devemos sempre informar todas as tabelas que serão relacionadas na clausula from e todos os seus relacionamentos na clausula where se por acaso não for feito o relacionamento de uma destas tabelas o banco de dados estará fazendo um produto cartesiano (CROSS JOIN) entre todas as linhas da tabela que não foi relacionado com as demais tabelas.Se isto acontecer o servidor poderá ter sérios problemas de uso excessivo de CPU.

Existem Cinco tipos de JOINS :

3.10.1.1. INNER JOIN

Um join simples é formado pelo relacionamento de duas ou mais tabelas.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Page 16: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME FROM SC5990 SC5, SA1990 SA1, SA3990 SA3 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SA3.A3_FILIAL = ‘01’ AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

3.10.1.2. LEFT JOIN ou LEFT OUTER JOIN

O resultado de um left join inclui todas as linhas da tabela que foi específica a esquerda da clausula LEFT OUTER , ou seja, independente de existir ou não um dado relacionado na tabela informada mais a direita da tabela todas as linhas referentes a tabela da esquerda serão retornadas. Nas linhas que não existe um linha de relação com a tabela a direita os campos desta tabela serão retornados com valor nulo.

O símbolo ( *= ) representa um LEFT JOIN para o MSSQL Server, Sybase, o campo indicado do lado do símbolo (*) será o da tabela que você deseja que todas as linhas sejam retornadas independente da existência do dado da coluna mais a direita, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SC5.C5_CLIENTE *= SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI *= SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME FROM SC5990 SC5, SA1990 SA1, SA3990 SA3 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SA3.A3_FILIAL = ‘01’ AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SA1.A1_VEND *= SA3.A3_COD <= Define o rel.SA1->SA3 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Page 17: SQL Protheus

Programação SQL com SIGA Advanced / AP5

O símbolo (+ ) representa um LEFT JOIN para o Oracle, o campo indicado do lado do campo que será o da tabela que você deseja que todas as linhas sejam retornadas independente da existência do dado da coluna mais a direita, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND (+) SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND (+) SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME FROM SC5990 SC5, SA1990 SA1, SA3990 SA3 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SA3.A3_FILIAL = ‘01’ AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND (+) SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Na clausula from especificamos a palavra OUTER que irá representar um LEFT JOIN para o Informix, o campo da esquerda será o da tabela que você deseja que todas as linhas sejam retornadas independente da existência do dado da coluna mais a direita, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5 OUTER, SA1990 SA1 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME FROM SC5990 SC5, SA1990 SA1 OUTER, SA3990 SA3 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SA3.A3_FILIAL = ‘01’

Page 18: SQL Protheus

Programação SQL com SIGA Advanced / AP5

AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Nota: Não é possível fazer outer joins subsequentes, ou seja, se você fizer outer join de uma tabela que logo em seguida tem um relacionamento com outra tabela.

3.10.1.3. RIGHT JOIN or RIGHT OUTER JOIN

O resultado de um Right join inclui todas as linhas da tabela que foi específica a direita da clausula RIGHT OUTER , ou seja, independente de existir ou não um dado relacionado na tabela informada mais a esquerda da tabela todas as linhas referentes a tabela da direita serão retornadas. Nas linhas que não existe um linha de relação com a tabela a direita os campos desta tabela serão retornados com valor nulo.

O símbolo ( =* ) representa um RIGHT JOIN para o MSSQL Server, Sybase, o campo indicado do lado do símbolo (*) será o da tabela que você deseja que todas as linhas sejam retornadas independente da existência do dado da coluna mais a esquerda, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todos os clientes mesmo que não exista pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SC5.C5_CLIENTE =* SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI =* SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

O símbolo ( + ) representa um RIGHT JOIN para o Oracle, o campo indicado do lado do símbolo (+) será o da tabela que você deseja que todas as linhas sejam retornadas independente da existência do dado da coluna mais a esquerda, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todos os clientes mesmo que não exista pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SC5.C5_CLIENTE = SA1.A1_COD (+) <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA (+) <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Page 19: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Na clausula from especificamos a palavra OUTER que irá representar um RIGHT JOIN para o Informix, o campo indicado do lado direito que você deseja que todas as linhas sejam retornadas independente da existência do dado da coluna mais a esquerda, vamos ver exemplos de query’s para estes Bancos de Dados.

Ex. Select para retornar todos os clientes mesmo que não exista pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 OUTER WHERE SC5.C5_FILIAL = '01'

AND SA1.A1_FILIAL = ' ' AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Nota: Não é possível fazer outer joins subsequentes, ou seja, se você fizer outer join de uma tabela que logo em seguida tem um relacionamento com outra tabela.

3.10.1.4. FULL JOIN or FULL OUTER JOIN

Um full outer join é o resultado de um inner join + right join + left join , desta forma você terá o resultado com todas as linhas da primeira tabela mais o resultado com todas as linhas da Segunda tabela e apresentará em mesma linha os itens que forem possíveis de relacionamento.

Exemplo para o Banco MSSQL Server e Sybase

Ex. Select para retornar todos os clientes e todos os pedidos mesmo que não exista pedidos ou clientes relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5 FULL OUTER SA1990 SA1

ON SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 WHERE SC5.C5_FILIAL = '01' AND SA1.A1_FILIAL = ' ' AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Nota: Nos demais Bancos de Dados não existem este tipo de join. Mas existem outras formar de resolver este problema utilizando inner join + left join + right join + unions , iremos ver a seguir como utilizar o union desta forma teremos a solução também para os demais bancos de dados, e até mesmo os que tem a opção.

3.10.1.5. CROSS JOIN

É o mais simples e dificilmente utilizado, ele simplesmente faz um produto cartesiano em as tabelas especificadas na clausula where. O comando é o mesmo em todos os Bancos de Dados.

Ex. Select para retornar todos os clientes e todos os pedidos mesmo que não exista pedidos ou clientes relacionados

Page 20: SQL Protheus

Programação SQL com SIGA Advanced / AP5

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1

Nota: Existem vários casos de programadores que esquecem de relacionar algumas tabelas, e acontece um grande problema de performance. Se você esquecer de relacionar uma tabela e a mesma tiver um número de linhas muito grande nós estaremos consumindo processador e i/o de disco inutilmente.

3.11. UNIONS

A expressão UNION permite você combinar o resultado de dois ou mais SELECTs em um único resultado. Uma das restrições para combinar o uso de UNION é que devemos ter uma estrutura única em cada um dos SELECTs, ou seja, os mesmos devem ter o mesmo número de colunas devem ter tipos de dados compatíveis.

Ex. Select para retornar todos os clientes da empresa 01 e da empresa 02 desconsiderando duplicidades

SELECT A1_COD, A1_LOJA, A1_NOME FROM SA1990 UNIONSELECT A1_COD, A1_LOJA, A1_NOME FROM SA1010

Ex. Select para retornar todos os clientes da empresa 01 e da empresa 02 considerando todas duplicidades

SELECT A1_COD, A1_LOJA, A1_NOME FROM SA1990 UNION ALLSELECT A1_COD, A1_LOJA, A1_NOME FROM SA1010

Nota: Existem vários casos de programadores que esquecem de informar a clausula ALL , e acontece um grande problema que parece estar faltando registros de dados nos programas.

Page 21: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.12. SUB SELECTS

Sub-Selects é utilizado na clausula where onde pode ser utilizado para fazer relação de verificação de um determinado dado da tabela original com várias linhas de uma outra tabela sem obrigatoriamente ser parte integrante de um join.

Ex. Select para retornar todos os clientes que compraram o produto ‘x’, utilizando operador IN

SELECT DISTINCT SA1.A1_NOME FROM SA1990 SA1, SC5990 SC5

WHERE SA1.A1_FILIAL = ' ' AND SC5.C5_FILIAL = '01' AND SC5.C5_CLIENTE = SA1.A1_COD AND SC5.C5_LOJACLI = SA1.A1_LOJA AND SC5.C5_NUM IN ( SELECT C6_NUM

FROM SC6990 SC6 WHERE SC6.FILIAL = ‘ ’ AND SC6.C6_NUM = SC5.C5_NUM AND SC6.C6_PRODUTO = ‘X’ AND SC6.D_E_L_E_T_ <> ‘*’ )

AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

Ex. Select para retornar todos os clientes que compraram o produto ‘x’, utiliando operador EXISTS

SELECT DISTINCT SA1.A1_NOME FROM SA1990 SA1, SC5990 SC5

WHERE SA1.A1_FILIAL = ' ' AND SC5.C5_FILIAL = '01' AND SC5.C5_CLIENTE = SA1.A1_COD AND SC5.C5_LOJACLI = SA1.A1_LOJA AND EXISTS ( SELECT *

FROM SC6990 SC6 WHERE SC6.FILIAL = ‘ ’ AND SC6.C6_NUM = SC5.C5_NUM AND SC6.C6_PRODUTO = ‘X’ AND SC6.D_E_L_E_T_ <> ‘*’ )

AND SC5.D_E_L_E_T_ <> '*' AND SA1.D_E_L_E_T_ <> '*'

3.13. TRIGGERS

Triggers são gatilhos do Banco de Dados, os quais são acionados por uma inclusão, alteração ou exclusão de uma linha em uma determinada tabela. Cada Banco de Dados trata as triggers de uma forma, hoje o SigaAdvanced/AP5 não utiliza estas triggers. As triggers podem ser utilizadas pelos clientes, considerando o seguinte problema: Se houver qualquer alteração na estrutura de uma tabela o sistema irá reconstruir a tabela mas com sua nova estrutura, índices, defaults, ..., mas não irá recriar os triggers criados associados a estas tabelas.

Page 22: SQL Protheus

Programação SQL com SIGA Advanced / AP5

3.14. STORED PROCEDURES

Stored Procedures são programas feitos em linguagem nativa do Banco de Dados em questão que não utiliza o padrão ANSI/92, uma Stored Procedure pode resolver vários problemas de performance, por que uma procedure além de estar sendo executada no próprio Banco de dados que elimina o tráfego de rede, ela já foi pré-compilada, ou seja, ela não passa por uma re-compilação a cada vez que ela é executada.

A Microsiga utiliza várias Storeds Procedures em processos críticos para clientes com Base de Dados muito grande, em clientes pequenos este processo não se faz necessário, além de que clientes menores utilizam servidores menores que nem sempre tem capacidade suficiente para executar SP’s.

Como cada Banco de Dados possui Stored Procedures diferentes a Microsiga criou o seu compilador que chamamos SQLParser e adotamos um dialeto único e um único fonte o qual é convertido para cada tipo de Banco de Dados, evitando desta forma divergência entre programas fontes.

3.15. CURSORES

Cursores são definições de conjunto de dados que serão manipulados linha a linha, ou seja, da mesma forma que estamos acostumados a fazer uma linguagem posicional onde os registros são tratados um a um.

4. Programando SQL em RDMAKES 4.1. Query’s

Agora vamos ver um exemplo prático utilizando query diretamente no Banco de Dados

Programa interno do SigaAdvanced/AP5 As linhas em negrito são as modificações para utilizar linguagem SQL

//³Funcao ³ FA130Imp //³Descricao ³ Imprime relatorio dos Titulos a Receber//³Sintaxe e ³ FA130Imp(lEnd,WnRel,cString)Static Function FA130Imp(lEnd,WnRel,cString)Local CbContLocal CbTxtLocal limite := 220Local nOrdemLocal lContinua := .T.Local cCond1,cCond2,cCarAntLocal nTit0:=0Local nTit1:=0Local nTit2:=0Local nTit3:=0Local nTit4:=0Local nTit5:=0Local nTotJ:=0Local nTot0:=0Local nTot1:=0Local nTot2:=0Local nTot3:=0Local nTot4:=0Local nTotTit:=0Local nTotJur:=0Local nTotFil0:=0Local nTotFil1:=0

Page 23: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Local nTotFil2:=0Local nTotFil3:=0Local nTotFil4:=0Local nTotFilTit:=0Local nTotFilJ:=0Local aCampos:={}Local aTam:={}Local nAtraso:=0Local nTotAbat:=0Local nSaldo:=0Local dDataReajLocal dDataAnt := dDataBaseLocal lQuebraLocal nMesTit0 := 0Local nMesTit1 := 0Local nMesTit2 := 0Local nMesTit3 := 0Local nMesTit4 := 0Local nMesTTit := 0Local nMesTitj := 0Local cIndexSe1Local cChaveSe1Local nIndexSE1Local dDtContabLocal cTipos := ""Local aStru := SE1->(dbStruct()), niLocal nTotsRec := SE1->(RecCount())

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Ponto de entrada para Filtrar os tipos sem entrar na tela do ³//³ FINRTIPOS(), localizacao Argentina. ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄJose Lucas, Localiza‡”es ArgentinaÄÙIF EXISTBLOCK("F130FILT")

cTipos := EXECBLOCK("F130FILT",.f.,.f.)ENDIF

nOrdem:=aReturn[8]cMoeda:=Str(mv_par15,1)

PRIVATE dBaixa := dDataBasePRIVATE cFilDe,cFilAte

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Vari veis utilizadas para Impress„o do Cabe‡alho e Rodap‚ ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙcbtxt := "* indica titulo provisorio, P Indica Saldo Parcial"cbcont := 1li := 80m_pag := 1

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ POR MAIS ESTRANHO QUE PARE€A, ESTA FUNCAO DEVE SER CHAMADA AQUI! ³//³ ³//³ A fun‡„o SomaAbat reabre o SE1 com outro nome pela ChkFile para ³//³ efeito de performance. Se o alias auxiliar para a SumAbat() n„o ³//³ estiver aberto antes da IndRegua, ocorre Erro de & na ChkFile, ³//³ pois o Filtro do SE1 uptrapassa 255 Caracteres. ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙSomaAbat("","","","R")

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Atribui valores as variaveis ref a filiais ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIf mv_par21 == 2

cFilDe := cFilAntcFilAte:= cFilAnt

ELSEcFilDe := mv_par22 // Todas as filiaiscFilAte:= mv_par23

Page 24: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Endif

dbSelectArea("SM0")dbSeek(cEmpAnt+cFilDe,.T.)

While !Eof() .and. M0_CODIGO == cEmpAnt .and. M0_CODFIL <= cFilAte

dbSelectArea("SE1")cFilAnt := SM0->M0_CODFILSet Softseek On

If mv_par19 == 1titulo := titulo + OemToAnsi(STR0026) //" - Analitico"

Elsetitulo := titulo + OemToAnsi(STR0027) //" - Sintetico"cabec1 := OemToAnsi(STR0044) //" |

Titulos Vencidos | Titulos a Vencer | Vlr.juros ou (Vencidos+Vencer)"cabec2 := OemToAnsi(STR0045) //" | Valor

Nominal Valor Corrigido | Valor Nominal | permanencia "EndIf

#IFDEF TOP if TcSrvType() != "AS/400"

cQuery := "SELECT * "cQuery += " FROM "+ RetSqlName("SE1")cQuery += " WHERE E1_FILIAL Between '" + cFilDe + "' AND '"+ cFilAte + "'"cQuery += " AND D_E_L_E_T_ <> '*' "

endif #ENDIF

IF nOrdem = 1cChaveSe1 :=

"E1_FILIAL+E1_NOMCLI+E1_CLIENTE+E1_LOJA+E1_PREFIXO+E1_NUM+E1_PARCELA+E1_TIPO" #IFDEF TOP if TcSrvType() == "AS/400" cIndexSe1 := CriaTrab(nil,.f.)

IndRegua("SE1",cIndexSe1,cChaveSe1,,Fr130IndR(),"Selecionando Registros...")nIndexSE1 := RetIndex("SE1")dbSetOrder(nIndexSe1+1)dbSeek(xFilial("SE1"))

else cOrder := SqlOrder(cChaveSe1) endif #ELSE

cIndexSe1 := CriaTrab(nil,.f.)IndRegua("SE1",cIndexSe1,cChaveSe1,,Fr130IndR(),"Selecionando Registros...")nIndexSE1 := RetIndex("SE1")dbSetIndex(cIndexSe1+OrdBagExt())dbSetOrder(nIndexSe1+1)dbSeek(xFilial("SE1"))

#ENDIFcCond1 := "E1_CLIENTE <= mv_par02"cCond2 := "E1_CLIENTE + E1_LOJA"titulo := titulo + OemToAnsi(STR0017) //" - Por Cliente"

Elseif nOrdem = 2SE1->(dbSetOrder(1))#IFNDEF TOP

dbSeek(cFilial+mv_par03+mv_par05)#ELSE

if TcSrvType() == "AS/400"dbSeek(cFilial+mv_par03+mv_par05)

elsecOrder := SqlOrder(IndexKey())

endif#ENDIFcCond1 := "E1_NUM <= mv_par06"cCond2 := "E1_NUM"titulo := titulo + OemToAnsi(STR0018) //" - Por Numero"

Elseif nOrdem = 3

Page 25: SQL Protheus

Programação SQL com SIGA Advanced / AP5

SE1->(dbSetOrder(4))#IFNDEF TOP

dbSeek(cFilial+mv_par07)#ELSE

if TcSrvType() == "AS/400"dbSeek(cFilial+mv_par07)

elsecOrder := SqlOrder(IndexKey())

endif#ENDIFcCond1 := "E1_PORTADO <= mv_par08"cCond2 := "E1_PORTADO"titulo := titulo + OemToAnsi(STR0019) //" - Por Banco"

Elseif nOrdem = 4SE1->(dbSetOrder(7))#IFNDEF TOP

dbSeek(cFilial+DTOS(mv_par09))#ELSE

if TcSrvType() == "AS/400"dbSeek(cFilial+DTOS(mv_par09))

elsecOrder := SqlOrder(IndexKey())

endif#ENDIFcCond1 := "E1_VENCREA <= mv_par10"cCond2 := "E1_VENCREA"titulo := titulo + OemToAnsi(STR0020) //" - Por Data de Vencimento"

Elseif nOrdem = 5SE1->(dbSetOrder(3))#IFNDEF TOP

dbSeek(cFilial+mv_par11)#ELSE

if TcSrvType() == "AS/400"dbSeek(cFilial+mv_par11)

elsecOrder := SqlOrder(IndexKey())

endif#ENDIFcCond1 := "E1_NATUREZ <= mv_par12"cCond2 := "E1_NATUREZ"titulo := titulo + OemToAnsi(STR0021) //" - Por Natureza"

Elseif nOrdem = 6SE1->(dbSetOrder(6))#IFNDEF TOP

dbSeek( cFilial+DTOS(mv_par13))#ELSE

if TcSrvType() == "AS/400"dbSeek( cFilial+DTOS(mv_par13))

elsecOrder := SqlOrder(IndexKey())

endif#ENDIFcCond1 := "E1_EMISSAO <= mv_par14"cCond2 := "E1_EMISSAO"titulo := titulo + OemToAnsi(STR0042) //" - Por Emissao"

Elseif nOrdem == 7cChaveSe1 := "E1_FILIAL+DTOS(E1_VENCREA)

+E1_PORTADO+E1_PREFIXO+E1_NUM+E1_PARCELA+E1_TIPO"#IFNDEF TOP

cIndexSe1 := CriaTrab(nil,.f.)IndRegua("SE1",cIndexSe1,cChaveSe1,,Fr130Ind7(),"Selecionando Registros...")nIndexSE1 := RetIndex("SE1")dbSetIndex(cIndexSe1+OrdBagExt())dbSetOrder(nIndexSe1+1)dbSeek(xFilial("SE1"))

#ELSE if TcSrvType() == "AS/400"

cIndexSe1 := CriaTrab(nil,.f.)IndRegua("SE1",cIndexSe1,cChaveSe1,,Fr130Ind7(),"Selecionando Registros...")nIndexSE1 := RetIndex("SE1")

Page 26: SQL Protheus

Programação SQL com SIGA Advanced / AP5

dbSetOrder(nIndexSe1+1)dbSeek(xFilial("SE1"))

elsecOrder := SqlOrder(cChaveSe1)

endif#ENDIFcCond1 := "E1_VENCREA <= mv_par10"cCond2 := "DtoS(E1_VENCREA)+E1_PORTADO"titulo := titulo + OemToAnsi(STR0023) //" - Por Vencto/Banco"

Elseif nOrdem = 8SE1->(dbSetOrder(2))#IFNDEF TOP

dbSeek(cFilial+mv_par01,.T.)#ELSE

if TcSrvType() == "AS/400"dbSeek(cFilial+mv_par01,.T.)

elsecOrder := SqlOrder(IndexKey())

endif#ENDIFcCond1 := "E1_CLIENTE <= mv_par02"cCond2 := "E1_CLIENTE"titulo := titulo + OemToAnsi(STR0024) //" - Por Cod.Cliente"

Elseif nOrdem = 9cChave :=

"E1_FILIAL+E1_PORTADO+E1_SITUACA+E1_NOMCLI+E1_PREFIXO+E1_NUM+E1_PARCELA+E1_TIPO"#IFNDEF TOP

dbSelectArea("SE1")cIndex := CriaTrab(nil,.f.)IndRegua("SE1",cIndex,cChave,,fr130cheq(),"Selecionando Registros...")nIndex := RetIndex("SE1")dbSetIndex(cIndex+OrdBagExt())dbSetOrder(nIndex+1)dbSeek(xFilial("SE1"))

#ELSE if TcSrvType() == "AS/400"

dbSelectArea("SE1")cIndex := CriaTrab(nil,.f.)IndRegua("SE1",cIndex,cChave,,fr130cheq(),"Selecionando Registros...")nIndex := RetIndex("SE1")dbSetOrder(nIndex+1)dbSeek(xFilial("SE1"))

elsecOrder := SqlOrder(cChave)

endif#ENDIFcCond1 := "E1_PORTADO <= mv_par08"cCond2 := "E1_PORTADO+E1_SITUACA"titulo := titulo + OemToAnsi(STR0025) //" - Por Banco e Situacao"

Endif

If mv_par19 == 1titulo := titulo + OemToAnsi(STR0026) //" - Analitico"

Elsetitulo := titulo + OemToAnsi(STR0027) //" - Sintetico"cabec1 := OemToAnsi(STR0044) //"Nome do Cliente |

Titulos Vencidos | Titulos a Vencer | Vlr.juros ou (Vencidos+Vencer)"cabec2 := OemToAnsi(STR0045) //" | Valor

Nominal Valor Corrigido | Valor Nominal | permanencia "EndIf

cFilterUser:=aReturn[7]Set Softseek Off

#IFDEF TOPif TcSrvType() != "AS/400"

cQuery += " AND E1_CLIENTE between '" + mv_par01 + "' AND '" + mv_par02 + "'"cQuery += " AND E1_PREFIXO between '" + mv_par03 + "' AND '" + mv_par04 + "'"cQuery += " AND E1_NUM between '" + mv_par05 + "' AND '" + mv_par06 + "'"cQuery += " AND E1_PORTADO between '" + mv_par07 + "' AND '" + mv_par08 + "'"

Page 27: SQL Protheus

Programação SQL com SIGA Advanced / AP5

cQuery += " AND E1_VENCREA between '" + DTOS(mv_par09) + "' AND '" + DTOS(mv_par10) + "'"cQuery += " AND E1_NATUREZ between '" + mv_par11 + "' AND '" + mv_par12 + "'"cQuery += " AND E1_EMISSAO between '" + DTOS(mv_par13) + "' AND '" + DTOS(mv_par14) + "'"cQuery += " AND E1_LOJA between '" + mv_par24 + "' AND '" + mv_par25 + "'"cQuery += " AND E1_EMISSAO <= '" + DTOS(dDataBase) + "'"

If mv_par20 == 2cQuery += ' AND E1_SALDO <> 0'

EndifcQuery += " ORDER BY "+ cOrder

cQuery := ChangeQuery(cQuery)

dbSelectArea("SE1")dbCloseArea()dbSelectArea("SA1")

dbUseArea(.T., "TOPCONN", TCGenQry(,,cQuery), 'SE1', .F., .T.) //= O mesmo que TCQUERY

For ni := 1 to Len(aStru)If aStru[ni,2] != 'C'

TCSetField('SE1', aStru[ni,1], aStru[ni,2],aStru[ni,3],aStru[ni,4])Endif

Nextendif

#ENDIFSetRegua(nTotsRec)

While &cCond1 .and. !Eof() .and. lContinua .and. E1_FILIAL == xFilial("SE1")

#IFNDEF WINDOWSInkey()If LastKey() = K_ALT_A

lEnd := .t.Endif

#ENDIF

IF lEnd@PROW()+1,001 PSAY OemToAnsi(STR0028) //"CANCELADO PELO OPERADOR"Exit

Endif

IncRegua()

Store 0 To nTit1,nTit2,nTit3,nTit4,nTit5

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Carrega data do registro para permitir ³//³ posterior analise de quebra por mes. ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙdDataAnt := Iif(nOrdem == 6 , SE1->E1_EMISSAO, SE1->E1_VENCREA)

cCarAnt := &cCond2

While &cCond2==cCarAnt .and. !Eof() .and. lContinua .and. E1_FILIAL == xFilial("SE1")

#IFNDEF WINDOWSInkey()If LastKey() = K_ALT_A

lEnd := .t.Endif

#ENDIF

IF lEnd@PROW()+1,001 PSAY OemToAnsi(STR0028) //"CANCELADO PELO OPERADOR"lContinua := .F.Exit

EndIF

IncRegua()

Page 28: SQL Protheus

Programação SQL com SIGA Advanced / AP5

dbSelectArea("SE1") //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿

//³ Filtrar com base no Pto de entrada do Usuario... ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄJose Lucas, Localiza‡”es ArgentinaÄÙ

If !Empty(cTipos)If !(SE1->E1_TIPO $ cTipos)

dbSkip()Loop

End Endif

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Considera filtro do usuario ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIf !Empty(cFilterUser).and.!(&cFilterUser)

dbSkip()Loop

Endif

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Nao ‚ retroativo, nem considera o titulo zerado ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIf mv_par20 == 2 .and. E1_SALDO = 0

dbSkip()Loop

Endif

IF !Empty(E1_FATURA) .and. Substr(E1_FATURA,1,6) != "NOTFAT" .and. SE1->E1_DTFATUR <= dDataBase

dbSkip()Loop

Endif

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Verifica se trata-se de abatimento ou somente titulos³//³ at‚ a data base. ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIF SubStr(SE1->E1_TIPO,3,1)=="-".Or. SE1->E1_EMISSAO>dDataBase .or.;

(!Empty(E1_FATURA).and.Substr(E1_FATURA,1,6)=="NOTFAT".and.SE1->E1_EMISSAO > dDataBase)

dbSkip()Loop

Endif

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Verifica se ser  impresso titulos provis¢rios ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIF E1_TIPO == "PR " .and. mv_par16 == 2

dbSkip()Loop

Endif

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Verifica se ser  impresso titulos de Adiantamento ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIF SE1->E1_TIPO $ "RA /"+MV_CRNEG .and. mv_par26 == 2

dbSkip()Loop

Endif

// dDtContab para casos em que o campo E1_EMIS1 esteja vaziodDtContab := Iif(Empty(SE1->E1_EMIS1),SE1->E1_EMISSAO,SE1->E1_EMIS1)

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Verifica se esta dentro dos parametros ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙdbSelectArea("SE1")IF SE1->E1_CLIENTE < mv_par01 .OR. SE1->E1_CLIENTE > mv_par02 .OR. ;

SE1->E1_PREFIXO < mv_par03 .OR. SE1->E1_PREFIXO > mv_par04 .OR. ;

Page 29: SQL Protheus

Programação SQL com SIGA Advanced / AP5

SE1->E1_NUM < mv_par05 .OR. SE1->E1_NUM > mv_par06 .OR. ;

SE1->E1_PORTADO < mv_par07 .OR. SE1->E1_PORTADO > mv_par08 .OR. ;SE1->E1_VENCREA < mv_par09 .OR. SE1->E1_VENCREA > mv_par10 .OR. ;SE1->E1_NATUREZ < mv_par11 .OR. SE1->E1_NATUREZ > mv_par12 .OR. ;SE1->E1_EMISSAO < mv_par13 .OR. SE1->E1_EMISSAO > mv_par14 .OR. ;SE1->E1_LOJA < mv_par24 .OR. SE1->E1_LOJA > mv_par25 .OR. ;dDtContab < mv_par27 .OR. dDtContab > mv_par28 .OR. ;SE1->E1_EMISSAO > dDataBasedbSkip()Loop

Endif

If mv_par18 == 2 .and. E1_SITUACA $ "27"dbSkip()Loop

Endif

dDataReaj := IIF(SE1->E1_VENCREA < dDataBase ,;IIF(mv_par17=1,dDataBase,E1_VENCREA),;dDataBase)

If mv_par20 == 1 // Considera Data BasenSaldo :=SaldoTit(SE1->E1_PREFIXO,SE1->E1_NUM,SE1->E1_PARCELA,SE1-

>E1_TIPO,SE1->E1_NATUREZ,"R",SE1->E1_CLIENTE,mv_par15,dDataReaj,,SE1->E1_LOJA)Else

nSaldo := xMoeda(SE1->E1_SALDO,SE1->E1_MOEDA,mv_par15,dDataReaj)Endif

If ! (SE1->E1_TIPO $ "RA /"+MV_CRNEG) .And. ;!( MV_PAR20 == 2 .And. nSaldo == 0 ) // nao deve olhar abatimento pois e zerado o saldo na

liquidacao final do titulonSaldo-=SomaAbat(SE1->E1_PREFIXO,SE1->E1_NUM,SE1-

>E1_PARCELA,"R",mv_par15,dDataReaj,SE1->E1_CLIENTE,SE1->E1_LOJA)EndIfnSaldo:=Round(NoRound(nSaldo,3),2)

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Desconsidera caso saldo seja menor ou igual a zero ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙIf nSaldo <= 0

dbSkip()Loop

Endif

dbSelectArea("SA1")MSSeek(cFilial+SE1->E1_CLIENTE+SE1->E1_LOJA)dbSelectArea("SA6")MSSeek(cFilial+SE1->E1_PORTADO)dbSelectArea("SE1")

IF li > 58cabec(titulo,cabec1,cabec2,nomeprog,tamanho,GetMv("MV_COMP"))

EndIF

If mv_par19 == 1@li, 0 PSAY SE1->E1_CLIENTE@li, 7 PSAY SubStr( SE1->E1_NOMCLI, 1, 20 )@li, 28 PSAY SE1->E1_PREFIXO+"-"+SE1->E1_NUM+"-"+SE1->E1_PARCELA@li, 47 PSAY SE1->E1_TIPO@li, 51 PSAY SE1->E1_NATUREZ@li, 62 PSAY SE1->E1_EMISSAO@li, 73 PSAY SE1->E1_VENCTO@li, 84 PSAY SE1->E1_VENCREA@li, 95 PSAY SE1->E1_PORTADO+" "+SE1->E1_SITUACA@li,101 PSAY xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1->E1_EMISSAO)

Picture tm ( SE1->E1_VALOR, 14 )Endif

If dDataBase > E1_VENCREA //vencidos

Page 30: SQL Protheus

Programação SQL com SIGA Advanced / AP5

If mv_par19 == 1@li, 116 PSAY nSaldo Picture tm ( nSaldo, 14 )

EndIfnJuros:=0fa070Juros(mv_par15)dbSelectArea("SE1")If mv_par19 == 1

@li,133 PSAY nSaldo+nJuros Picture tm(nSaldo+nJuros,14)EndIfIf SE1->E1_TIPO $ "RA /"+MV_CRNEG

nTit0 -= xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1->E1_EMISSAO)

nTit1 -= (nSaldo)nTit2 -= (nSaldo+nJuros)nMesTit0 -= xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1-

>E1_EMISSAO)nMesTit1 -= (nSaldo)nMesTit2 -= (nSaldo+nJuros)

ElsenTit0 += xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1-

>E1_EMISSAO)nTit1 += (nSaldo)nTit2 += (nSaldo+nJuros)nMesTit0 += xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1-

>E1_EMISSAO)nMesTit1 += (nSaldo)nMesTit2 += (nSaldo+nJuros)

EndifnTotJur += nJurosnMesTitj += nJurosnTotFilJ += nJuros

Else //a vencerIf mv_par19 == 1

@li,149 PSAY nSaldo Picture tm ( nSaldo, 14 )EndIfIf ! ( SE1->E1_TIPO $ "RA /"+MV_CRNEG)

nTit0 += xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1->E1_EMISSAO)

nTit3 += (nSaldo-nTotAbat)nTit4 += (nSaldo-nTotAbat)nMesTit0 += xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1-

>E1_EMISSAO)nMesTit3 += (nSaldo-nTotAbat)nMesTit4 += (nSaldo-nTotAbat)

ElsenTit0 -= xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1-

>E1_EMISSAO)nTit3 -= (nSaldo-nTotAbat)nTit4 -= (nSaldo-nTotAbat)nMesTit0 -= xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1-

>E1_EMISSAO)nMesTit3 -= (nSaldo-nTotAbat)nMesTit4 -= (nSaldo-nTotAbat)

EndifEndif

If mv_par19 == 1@ li, 166 PSAY SE1->E1_NUMBCO

EndIfIf nJuros > 0

If mv_par19 == 1@ Li,177 PSAY nJuros Picture Tm(nJuros,12)

EndIfnJuros := 0

Endif

IF dDataBase > SE1->E1_VENCREAnAtraso:=dDataBase-SE1->E1_VENCTOIF Dow(SE1->E1_VENCTO) == 1 .Or. Dow(SE1->E1_VENCTO) == 7

IF Dow(dBaixa) == 2 .and. nAtraso <= 2

Page 31: SQL Protheus

Programação SQL com SIGA Advanced / AP5

nAtraso := 0EndIF

EndIFnAtraso:=IIF(nAtraso<0,0,nAtraso)IF nAtraso>0

If mv_par19 == 1@li ,193 PSAY nAtraso Picture "9999"

EndIfEndIF

EndIFIf mv_par19 == 1

@li,198 PSAY SubStr(SE1->E1_HIST,1,20)+ ;IIF(E1_TIPO=="PR ","*"," ")+ ;Iif(nSaldo == xMoeda(E1_VALOR,E1_MOEDA,mv_par15,dDataReaj)," ","P")

EndIf

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Carrega data do registro para permitir ³//³ posterior an lise de quebra por mes. ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙdDataAnt := Iif(nOrdem == 6, SE1->E1_EMISSAO, SE1->E1_VENCREA)dbSkip()nTotTit ++nMesTTit ++nTotFiltit++nTit5 ++If mv_par19 == 1

li++EndIf

Enddo

IF nTit5 > 0 .and. nOrdem != 2SubTot130(nTit0,nTit1,nTit2,nTit3,nTit4,nOrdem,cCarAnt,nTotJur)If mv_par19 == 1

Li++EndIf

Endif

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Verifica quebra por mˆs ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙlQuebra := .F.If nOrdem == 4 .and. Month(SE1->E1_VENCREA) # Month(dDataAnt)

lQuebra := .T.Elseif nOrdem == 6 .and. Month(SE1->E1_EMISSAO) # Month(dDataAnt)

lQuebra := .T.EndifIf lQuebra .and. nMesTTit # 0

ImpMes130(nMesTit0,nMesTit1,nMesTit2,nMesTit3,nMesTit4,nMesTTit,nMesTitJ)nMesTit1 := nMesTit2 := nMesTit3 := nMesTit4 := nMesTTit := nMesTitj := 0

EndifnTot0+=nTit0nTot1+=nTit1nTot2+=nTit2nTot3+=nTit3nTot4+=nTit4nTotJ+=nTotJur

nTotFil0+=nTit0nTotFil1+=nTit1nTotFil2+=nTit2nTotFil3+=nTit3nTotFil4+=nTit4Store 0 To nTit0,nTit1,nTit2,nTit3,nTit4,nTit5,nTotJur,nTotAbat

Enddo

dbSelectArea("SE1") // voltar para alias existente, se nao, nao funciona

//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Imprimir TOTAL por filial somente quan-³

Page 32: SQL Protheus

Programação SQL com SIGA Advanced / AP5

//³ do houver mais do que 1 filial. ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙif mv_par21 == 1 .and. SM0->(Reccount()) > 1

ImpFil130(nTotFil0,nTotFil1,nTotFil2,nTotFil3,nTotFil4,nTotFiltit,nTotFilJ)EndifStore 0 To nTotFil0,nTotFil1,nTotFil2,nTotFil3,nTotFil4,nTotFilTit,nTotFilJIf Empty(xFilial("SE1"))

ExitEndif

#IFDEF TOP if TcSrvType() != "AS/400"

dbSelectArea("SE1")dbCloseArea()ChKFile("SE1")dbSelectArea("SE1")dbSetOrder(1)

endif#ENDIF

dbSelectArea("SM0")dbSkip()

Enddo

IF li != 80IF li > 58

cabec(titulo,cabec1,cabec2,nomeprog,tamanho,GetMv("MV_COMP"))EndIFTotGer130(nTot0,nTot1,nTot2,nTot3,nTot4,nTotTit,nTotJ)Roda(cbcont,cbtxt,"G")

EndIF

Set Device To Screen

#IFNDEF TOPdbSelectArea("SE1")dbClearFil(NIL)RetIndex( "SE1" )If !Empty(cIndexSE1)

FErase (cIndexSE1+OrdBagExt())EndifdbSetOrder(1)

#ELSE if TcSrvType() != "AS/400"

dbSelectArea("SE1")dbCloseArea()ChKFile("SE1")

dbSelectArea("SE1")dbSetOrder(1)

elsedbSelectArea("SE1")dbClearFil(NIL)RetIndex( "SE1" )If !Empty(cIndexSE1)

FErase (cIndexSE1+OrdBagExt())EndifdbSetOrder(1)

endif#ENDIFIf aReturn[5] = 1

Set Printer TOdbCommitAll()Ourspool(wnrel)

EndifMS_FLUSH()Return

Page 33: SQL Protheus

Programação SQL com SIGA Advanced / AP5

Parte do Programa RDMAKE para execução de Query’s

//³Funcao ³ R170IMP //³Descricao ³ Chamada do Relatorio //³ Uso ³ MATR170

Function R170ImpdbSelectArea("SE2")dbSetOrder(8)cQuery := "SELECT E2_NATUREZ, E2_VENCREA, E2_NOMFOR, E2_PREFIXO, "cQuery := cQuery + " E2_NUM, E2_PARCELA, E2_VENCTO, E2_FORNECE, E2_LOJA," cQuery := cQuery + " E2_VALOR, E2_SALDO, E2_TIPO, E2_BAIXA, E2_EMISSAO"cQuery := cQuery + ‘ FROM RetSqlName("SE1") ‘ cQuery := cQuery + " WHERE E2_FILIAL = '" + xFilial("SE2") + "'"cQuery := cQuery + " AND D_E_L_E_T_ = ' ' "cQuery := cQuery + " AND E2_NATUREZ >= '"+ MV_PAR01 +"' AND E2_NATUREZ <= '"+mv_par02+"'"cQuery := cQuery + " AND E2_VENCREA >= '"+DTOS(mv_par03)+"' AND E2_VENCREA <= '"+DTOS(mv_par04)+"'"cQuery := cQuery + " AND E2_FORNECE >= '"+mv_par07+"' And E2_FORNECE <= '"+mv_par08+"'"cQuery := cQuery + " AND E2_EMISSAO >= '"+DTOS(mv_par09)+"' AND E2_EMISSAO <= '"+DTOS(mv_par10)+"'"cQuery := cQuery + " AND E2_TIPO <> 'AB-'" cQuery := cQuery + " ORDER BY E2_NATUREZ, E2_VENCREA, E2_NOMFOR"

cQuery := ChangeQuery(cQuery)

TCQUERY cQuery Alias TRB NewdbSelectArea("TRB")nCont := 0SetRegua(15000)//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿//³ Faz manualmente porque nao chama a funcao Cabec() ³//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ_nTotGer := 0li := 60cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1)li := 06

While !Eof()

IncRegua()

If li >56cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1)

End _cNatur :=TRB->E2_NATUREZdbSelectArea("SED")dbSetOrder(1)dbSeek(xFilial() + _cNatur)

_cDescNat := SED->ED_DESCRICli := li + 1

@ li, 001 PSAY "Natureza..: "+AllTrim(_cNatur) + " - " + _cDescNatli := li + 2dbSelectArea("TRB")_nTotNat := 0

While !Eof() .And. TRB->E2_NATUREZ == _cNatur

// Loop por Data _dVenc := TRB->E2_VENCREA

_nTotDia := 0

While !Eof() .And. TRB->E2_VENCREA == _dVenc .And. ; TRB->E2_NATUREZ == _cNatur

IncRegua()

Page 34: SQL Protheus

Programação SQL com SIGA Advanced / AP5

IF !Empty(TRB->E2_BAIXA) .and. TRB->E2_BAIXA <= DTOS(dDataBase) .and.; TRB->E2_SALDO == 0 dbSkip()

LoopEndIF

nAbatimentos:= 0_nTotAbat := 0nSaldo := 0_nSaldoT := 0

_nTotAbat:= nAbatimentos// ------------------------ Calcula o Saldo ----------------------//

fSaldoTit() _nSaldoT := nSaldo_nValor := _nSaldoT - _nTotAbat

//----------------------------------------------------//If _nValor <= 0

dbSelectArea("TRB")dbSkip()Loop

End //--------------------------- Imprime ---------------------//

dbSelectArea("SA2")dbSetOrder(1)dbSeek(xFilial() + TRB->E2_FORNECE + TRB->E2_LOJA)dbSelectArea("TRB")

@ li, 001 PSAY TRB->E2_FORNECE@ li, 008 PSAY SUBSTR(SA2->A2_NOME,1,20)

@ li, 029 PSAY TRB->E2_PREFIXO@ li, 033 PSAY TRB->E2_NUM@ li, 040 PSAY TRB->E2_PARCELA@ li, 042 PSAY TRB->E2_TIPO@ li, 045 PSAY SUBST(TRB->E2_EMISSAO,7,2)+"/"+SUBST(TRB-

>E2_EMISSAO,5,2)+"/"+SUBST(TRB->E2_EMISSAO,3,2)@ li, 055 PSAY SUBST(TRB->E2_VENCREA,7,2)+"/"+SUBST(TRB-

>E2_VENCREA,5,2)+"/"+SUBST(TRB->E2_VENCREA,3,2)@ li, 064 PSAY _nValor Picture"@E 9,999,999.99"@ li, 078 PSAY Iif((Val(Dtos(DDATABASE))-Val(TRB-

>E2_VENCREA))<=0,0,Val(Dtos(DDATABASE))-Val(TRB->E2_VENCREA)) Picture"@R 999"_nTotDia := _nTotDia + _nValordbSkip()li := li + 1If li >56

cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1)li := li + 1@ li, 001 PSAY "Natureza..: "+AllTrim(_cNatur) + " - " + SED->ED_DESCRIC + "

(continuacao)"li := li + 2

End EndIf _nTotDia > 0

li := li + 1@ li, 010 PSAY "Total do Dia.....: "@ li, 064 PSAY _nTotDia Picture"@E 9,999,999.99"li := li + 2_nTotNat := _nTotNat + _nTotDia

EndifEndli := li + 3@ li, 010 PSAY "Tot.Natureza " + AllTrim(_cNatur) + " - " + AllTrim(_cDescNat)@ li, 064 PSAY _nTotNat Picture"@E 9,999,999.99"_nTotGer := _nTotGer + _nTotNatli := 58

End@ li, 010 PSAY "Total do Relatorio..:"@ li, 062 PSAY _nTotGer Picture"@E 999,999,999.99"

Page 35: SQL Protheus

Programação SQL com SIGA Advanced / AP5

EJECT

dbSelectArea("TRB")dbCloseArea()RetIndex("SE2")dbSetOrder(1)Set device to ScreenIf aReturn[5] == 1

Set Printer TOdbcommitAll()ourspool(wnrel)

EndifMS_FLUSH()__Return()

Page 36: SQL Protheus

Programação SQL com SIGA Advanced / AP5

4.2. Função ChangeQuery , SQLOrder e RetSQLName

A função Changequery deve sempre ser executada antes de enviar uma query ao servidor, esta função tem como objetivo retornar a query modificada de acordo a melhorar forma possível de escrita para cada banco de dados, portanto para ela ser utilizada você deve utilizar o padrão ANSI de escrita, para depois a função ChangeQuery colocar o código específico de cada Banco de Dados.

A Função SQLOrder tem o objetivo de retornar uma chave de índice de uma determinada tabela no formato padrão para a utilização da clausula Order By, ou seja, o retorno da função indexkey(), retorno um chave por exemplo igual a (E1_FILIAL+E1_PREFIXO+E1_NUM+...), após execução desta função ele modifica para (E1_FILIAL,E1_PREFIXO,E1_NUM,...) para campos que contituem funções DTOS e STR também serão ajustados.

A função RetSQLName tem o objetivo de retornar o nome da tabela que se encontra na tabela SX2.

4.3. Stored Procedures

Função do Programa fonte onde é disparada a Stored Procedure

//³Funca ³A330Inicia//³Descricao ³ Pega valores do inicio do periodo para serem reprocessados ³±±//³ Uso ³ MATA330 ³±±

STATIC Function A330Inicia()#IFDEF TOPLocal cXFIlial,aResultIF !lCusFIFO .and. ExistProc('A330INI')

cxFilial := BuildStrFil("SD1,SD2,SD3,SF4,SB9,SF5,SB2,SC2")aResult := TCSPExec( xProcedures('A330INI'), cxFilial, Dtos(dINICIO),"@@",;

GetMv("MV_LOCPROC"), cFilAnt,;Substr(cUsuario,7,15), DTOS(dDataBase))

IF Len(aResult) = 0 .or. aResult[1] == "0"Final("Probs. SP. A330INI")

EndifElse

Xa330Inicia()EndifReturn Nil

Static Function Xa330Inicia()#ENDIFLOCAL nV,nX,bBloco:={ |nV,nX| Trim(nV)+STR(nX,1) }LOCAL aSaldoIni[07],cProduto:="",cLocal:=""LOCAL aSaldoFF[05]

… Continuação da função padrão para quando não houver Stored Procedure

Page 37: SQL Protheus

Programação SQL com SIGA Advanced / AP5

-- SQLParse - Microsiga Software SA -- Processado em 19/4/2000 09:36:15-- Dialeto: MSSql 6.5---------------------------------------- Criacao de procedure CREATE PROCEDURE A330INI_99 ( @IN_XFILIAL VARCHAR( 255 ) , @IN_DINICIO VARCHAR( 8 ) , @IN_CFILAUX VARCHAR( 02 ) , @IN_MV_LOCPROC VARCHAR( 02 ) , @IN_FILIALCOR VARCHAR( 02 ) , @IN_USER_LG VARCHAR( 17 ) , @IN_DATABASE VARCHAR( 08 ) , @OUT_RESULTADO VARCHAR( 1 ) output ) WITH ENCRYPTION AS -- Declaracoes de variaveisDECLARE @cCod VARCHAR( 15 )DECLARE @cLocal VARCHAR( 02 )DECLARE @nRecno INTEGERDECLARE @nQSALDOATU FLOATDECLARE @nCUSTOATU FLOATDECLARE @nCUSTOATU2 FLOATDECLARE @nCUSTOATU3 FLOATDECLARE @nCUSTOATU4 FLOATDECLARE @nCUSTOATU5 FLOATDECLARE @nQTSEGUM FLOATDECLARE @cFil_SB2 VARCHAR( 02 )DECLARE @cFil_SC2 VARCHAR( 02 )DECLARE @nRec INTEGERDECLARE @nRecAnt INTEGERDECLARE @nMaxRecnoSC2 INTEGERDECLARE @cFILAUX VARCHAR( 02 )BEGIN SELECT @OUT_RESULTADO = '0' SELECT @cFILAUX = @IN_CFILAUX IF @cFILAUX is null BEGIN SELECT @cFILAUX = ' ' END IF SUBSTRING ( @IN_XFILIAL , 7 , 1 ) = 'C' BEGIN SELECT @cFil_SB2 = ' ' END ELSE BEGIN SELECT @cFil_SB2 = @IN_FILIALCOR END IF SUBSTRING ( @IN_XFILIAL , 8 , 1 ) = 'C' BEGIN SELECT @cFil_SC2 = ' ' END ELSE BEGIN SELECT @cFil_SC2 = @IN_FILIALCOR END -- Declaracao do cursor CUR_A330INI DECLARE CUR_A330INI INSENSITIVE CURSOR FOR SELECT B2_COD , B2_LOCAL , R_E_C_N_O_ FROM SB2990 WHERE B2_FILIAL = @cFil_SB2 and B2_COD not like 'MOD%' and D_E_L_E_T_ <> '*' FOR READ ONLY OPEN CUR_A330INI FETCH CUR_A330INI INTO @cCod , @cLocal , @nRecno WHILE ( (@@fetch_status = 0 ) ) BEGIN

Page 38: SQL Protheus

Programação SQL com SIGA Advanced / AP5

EXEC MTXFUN1_99 @IN_XFILIAL , @cCod , @cLocal , @IN_DINICIO , @cFILAUX , @IN_MV_LOCPROC , @IN_FILIALCOR , @IN_USER_LG , @IN_DATABASE , @nQSALDOATU output , @nCUSTOATU output , @nCUSTOATU2 output , @nCUSTOATU3 output , @nCUSTOATU4 output , @nCUSTOATU5 output , @nQTSEGUM output IF @nQSALDOATU > 0 BEGIN UPDATE SB2990 SET B2_QFIM = @nQSALDOATU , B2_VFIM1 = @nCUSTOATU , B2_VFIM2 = @nCUSTOATU2 , B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 = @nCUSTOATU5 , B2_CM1 = @nCUSTOATU / @nQSALDOATU , B2_CM2 = @nCUSTOATU2 / @nQSALDOATU , B2_CM3 = @nCUSTOATU3 / @nQSALDOATU , B2_CM4 = @nCUSTOATU4 / @nQSALDOATU , B2_CM5 = @nCUSTOATU5 / @nQSALDOATU WHERE R_E_C_N_O_ = @nRecno END ELSE BEGIN UPDATE SB2990 SET B2_QFIM = @nQSALDOATU , B2_VFIM1 = @nCUSTOATU , B2_VFIM2 = @nCUSTOATU2 , B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 = @nCUSTOATU5 WHERE R_E_C_N_O_ = @nRecno END FETCH CUR_A330INI INTO @cCod , @cLocal , @nRecno END CLOSE CUR_A330INI DEALLOCATE CUR_A330INI SELECT @nMaxRecnoSC2 = MAX ( R_E_C_N_O_ ) FROM SC2990 WHERE C2_FILIAL = @cFil_SC2 IF @nMaxRecnoSC2 is null BEGIN SELECT @nMaxRecnoSC2 = 0 END SELECT @nRec = 0 WHILE (@nRec <= @nMaxRecnoSC2 ) BEGIN SELECT @nRecAnt = @nRec SELECT @nRec = @nRec + 1024 UPDATE SC2990 SET C2_VFIM1 = C2_VINI1 , C2_VFIM2 = C2_VINI2 , C2_VFIM3 = C2_VINI3 , C2_VFIM4 = C2_VINI4 , C2_VFIM5 = C2_VINI5 , C2_APRFIM1 = C2_APRINI1 , C2_APRFIM2 = C2_APRINI2 , C2_APRFIM3 = C2_APRINI3 , C2_APRFIM4 = C2_APRINI4 , C2_APRFIM5 = C2_APRINI5 WHERE R_E_C_N_O_ > @nRecAnt and R_E_C_N_O_ <= @nRec and C2_FILIAL = @cFil_SC2 END SELECT @OUT_RESULTADO = '1' END GO

Page 39: SQL Protheus

Programação SQL com SIGA Advanced / AP5

---------------------------------------- SQLParse - Microsiga Software SA -- Processado em 19/4/2000 09:36:16-- Dialeto: MSSql 7.0---------------------------------------- Criacao de procedure CREATE PROCEDURE A330INI_99 ( @IN_XFILIAL VarChar( 255 ) , @IN_DINICIO VarChar( 8 ) , @IN_CFILAUX VarChar( 02 ) , @IN_MV_LOCPROC VarChar( 02 ) , @IN_FILIALCOR VarChar( 02 ) , @IN_USER_LG VarChar( 17 ) , @IN_DATABASE VarChar( 08 ) , @OUT_RESULTADO VarChar( 1 ) output )

WITH ENCRYPTION AS -- Declaracoes de variaveisDECLARE @cCod VarChar( 15 )DECLARE @cLocal VarChar( 02 )DECLARE @nRecno IntegerDECLARE @nQSALDOATU FloatDECLARE @nCUSTOATU FloatDECLARE @nCUSTOATU2 FloatDECLARE @nCUSTOATU3 FloatDECLARE @nCUSTOATU4 FloatDECLARE @nCUSTOATU5 FloatDECLARE @nQTSEGUM FloatDECLARE @cFil_SB2 VarChar( 02 )DECLARE @cFil_SC2 VarChar( 02 )DECLARE @nRec IntegerDECLARE @nRecAnt IntegerDECLARE @nMaxRecnoSC2 IntegerDECLARE @cFILAUX VarChar( 02 )BEGIN SET @OUT_RESULTADO = '0' SET @cFILAUX = @IN_CFILAUX IF @cFILAUX is null BEGIN SET @cFILAUX = ' ' END IF SUBSTRING ( @IN_XFILIAL , 7 , 1 ) = 'C' BEGIN SET @cFil_SB2 = ' ' END ELSE BEGIN SET @cFil_SB2 = @IN_FILIALCOR END IF SUBSTRING ( @IN_XFILIAL , 8 , 1 ) = 'C' BEGIN SET @cFil_SC2 = ' ' END ELSE BEGIN SET @cFil_SC2 = @IN_FILIALCOR END -- Declaracao do cursor CUR_A330INI DECLARE CUR_A330INI INSENSITIVE CURSOR FOR SELECT B2_COD , B2_LOCAL , R_E_C_N_O_ FROM SB2990 WHERE B2_FILIAL = @cFil_SB2 and B2_COD not like 'MOD%' and D_E_L_E_T_ <> '*' FOR READ ONLY OPEN CUR_A330INI FETCH CUR_A330INI INTO @cCod , @cLocal , @nRecno

Page 40: SQL Protheus

Programação SQL com SIGA Advanced / AP5

WHILE ( (@@fetch_status = 0 ) ) BEGIN EXEC MTXFUN1_99 @IN_XFILIAL , @cCod , @cLocal , @IN_DINICIO , @cFILAUX , @IN_MV_LOCPROC , @IN_FILIALCOR , @IN_USER_LG , @IN_DATABASE , @nQSALDOATU output , @nCUSTOATU output , @nCUSTOATU2 output , @nCUSTOATU3 output , @nCUSTOATU4 output , @nCUSTOATU5 output , @nQTSEGUM output IF @nQSALDOATU > 0 BEGIN UPDATE SB2990 WITH (ROWLOCK) SET B2_QFIM = @nQSALDOATU , B2_VFIM1 = @nCUSTOATU , B2_VFIM2 = @nCUSTOATU2 , B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 = @nCUSTOATU5 , B2_CM1 = @nCUSTOATU / @nQSALDOATU , B2_CM2 = @nCUSTOATU2 / @nQSALDOATU , B2_CM3 = @nCUSTOATU3 / @nQSALDOATU , B2_CM4 = @nCUSTOATU4 / @nQSALDOATU , B2_CM5 = @nCUSTOATU5 / @nQSALDOATU WHERE R_E_C_N_O_ = @nRecno END ELSE BEGIN UPDATE SB2990 WITH (ROWLOCK) SET B2_QFIM = @nQSALDOATU , B2_VFIM1 = @nCUSTOATU , B2_VFIM2 = @nCUSTOATU2 , B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 = @nCUSTOATU5 WHERE R_E_C_N_O_ = @nRecno END FETCH CUR_A330INI INTO @cCod , @cLocal , @nRecno END CLOSE CUR_A330INI DEALLOCATE CUR_A330INI SELECT @nMaxRecnoSC2 = MAX ( R_E_C_N_O_ ) FROM SC2990 WHERE C2_FILIAL = @cFil_SC2 IF @nMaxRecnoSC2 is null BEGIN SET @nMaxRecnoSC2 = 0 END SET @nRec = 0 WHILE (@nRec <= @nMaxRecnoSC2 ) BEGIN SET @nRecAnt = @nRec SET @nRec = @nRec + 1024 UPDATE SC2990 WITH (ROWLOCK) SET C2_VFIM1 = C2_VINI1 , C2_VFIM2 = C2_VINI2 , C2_VFIM3 = C2_VINI3 , C2_VFIM4 = C2_VINI4 , C2_VFIM5 = C2_VINI5 , C2_APRFIM1 = C2_APRINI1 , C2_APRFIM2 = C2_APRINI2 , C2_APRFIM3 = C2_APRINI3 , C2_APRFIM4 = C2_APRINI4 , C2_APRFIM5 = C2_APRINI5 WHERE R_E_C_N_O_ > @nRecAnt and R_E_C_N_O_ <= @nRec and C2_FILIAL = @cFil_SC2 END SET @OUT_RESULTADO = '1' END GO

Page 41: SQL Protheus

Programação SQL com SIGA Advanced / AP5

---------------------------------------- SQLParse - Microsiga Software SA -- Processado em 19/4/2000 09:36:16-- Dialeto: Oracle---------------------------------------- Criacao de procedure CREATE OR REPLACE PROCEDURE A330INI_99 ( IN_XFILIAL in VARCHAR , IN_DINICIO in VARCHAR , IN_CFILAUX in VARCHAR , IN_MV_LOCPROC in VARCHAR , IN_FILIALCOR in VARCHAR , IN_USER_LG in VARCHAR , IN_DATABASE in VARCHAR , OUT_RESULTADO out VARCHAR ) IS -- Declaracoes de variaveisvcCod VARCHAR( 15 ) ;vcLocal VARCHAR( 02 ) ;vnRecno INTEGER ;vnQSALDOATU FLOAT ;vnCUSTOATU FLOAT ;vnCUSTOATU2 FLOAT ;vnCUSTOATU3 FLOAT ;vnCUSTOATU4 FLOAT ;vnCUSTOATU5 FLOAT ;vnQTSEGUM FLOAT ;vcFil_SB2 VARCHAR( 02 ) ;vcFil_SC2 VARCHAR( 02 ) ;vnRec INTEGER ;vnRecAnt INTEGER ;vnMaxRecnoSC2 INTEGER ;vcFILAUX VARCHAR( 02 ) ;

-- Declaracao do cursor CUR_A330INICURSOR CUR_A330INI ISSELECT B2_COD , B2_LOCAL , R_E_C_N_O_FROM SB2990WHERE B2_FILIAL = vcFil_SB2 and B2_COD not like 'MOD%' and D_E_L_E_T_ <> '*' ;

BEGIN OUT_RESULTADO := '0' ; vcFILAUX := IN_CFILAUX ; IF vcFILAUX is null THEN vcFILAUX := ' ' ; END IF; IF SUBSTR ( IN_XFILIAL , 7 , 1 ) = 'C' THEN vcFil_SB2 := ' ' ; ELSE vcFil_SB2 := IN_FILIALCOR ; END IF; IF SUBSTR ( IN_XFILIAL , 8 , 1 ) = 'C' THEN vcFil_SC2 := ' ' ; ELSE vcFil_SC2 := IN_FILIALCOR ; END IF; OPEN CUR_A330INI; FETCH CUR_A330INI INTO vcCod , vcLocal , vnRecno ; <<parse5>> WHILE ( (CUR_A330INI%FOUND ) ) LOOP MTXFUN1_99 (IN_XFILIAL , vcCod , vcLocal , IN_DINICIO , vcFILAUX , IN_MV_LOCPROC , IN_FILIALCOR , IN_USER_LG , IN_DATABASE , vnQSALDOATU , vnCUSTOATU , vnCUSTOATU2 , vnCUSTOATU3 , vnCUSTOATU4 , vnCUSTOATU5 , vnQTSEGUM ); IF vnQSALDOATU > 0 THEN

Page 42: SQL Protheus

Programação SQL com SIGA Advanced / AP5

UPDATE SB2990 SET B2_QFIM = vnQSALDOATU , B2_VFIM1 = vnCUSTOATU , B2_VFIM2 = vnCUSTOATU2 , B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 = vnCUSTOATU4 , B2_VFIM5 = vnCUSTOATU5 , B2_CM1 = vnCUSTOATU / vnQSALDOATU , B2_CM2 = vnCUSTOATU2 / vnQSALDOATU , B2_CM3 = vnCUSTOATU3 / vnQSALDOATU , B2_CM4 = vnCUSTOATU4 / vnQSALDOATU , B2_CM5 = vnCUSTOATU5 / vnQSALDOATU WHERE R_E_C_N_O_ = vnRecno ; ELSE UPDATE SB2990 SET B2_QFIM = vnQSALDOATU , B2_VFIM1 = vnCUSTOATU , B2_VFIM2 = vnCUSTOATU2 , B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 = vnCUSTOATU4 , B2_VFIM5 = vnCUSTOATU5 WHERE R_E_C_N_O_ = vnRecno ; END IF; FETCH CUR_A330INI INTO vcCod , vcLocal , vnRecno ; END LOOP; CLOSE CUR_A330INI; BEGIN SELECT MAX ( R_E_C_N_O_ ) INTO vnMaxRecnoSC2 FROM SC2990 WHERE C2_FILIAL = vcFil_SC2 ; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; IF vnMaxRecnoSC2 is null THEN vnMaxRecnoSC2 := 0 ; END IF; vnRec := 0 ; <<parse6>> WHILE (vnRec <= vnMaxRecnoSC2 ) LOOP vnRecAnt := vnRec ; vnRec := vnRec + 1024 ; UPDATE SC2990 SET C2_VFIM1 = C2_VINI1 , C2_VFIM2 = C2_VINI2 , C2_VFIM3 = C2_VINI3 , C2_VFIM4 = C2_VINI4 , C2_VFIM5 = C2_VINI5 , C2_APRFIM1 = C2_APRINI1 , C2_APRFIM2 = C2_APRINI2 , C2_APRFIM3 = C2_APRINI3 , C2_APRFIM4 = C2_APRINI4 , C2_APRFIM5 = C2_APRINI5 WHERE R_E_C_N_O_ > vnRecAnt and R_E_C_N_O_ <= vnRec and C2_FILIAL = vcFil_SC2 ; END LOOP; OUT_RESULTADO := '1' ;END;

Page 43: SQL Protheus

Programação SQL com SIGA Advanced / AP5

---------------------------------------- SQLParse - Microsiga Software SA -- Processado em 19/4/2000 09:36:16-- Dialeto: Informix---------------------------------------- Criacao de procedure CREATE PROCEDURE A330INI_99 ( IN_XFILIAL VARCHAR( 255 ) , IN_DINICIO VARCHAR( 8 ) , IN_CFILAUX VARCHAR( 02 ) , IN_MV_LOCPROC VARCHAR( 02 ) , IN_FILIALCOR VARCHAR( 02 ) , IN_USER_LG VARCHAR( 17 ) , IN_DATABASE VARCHAR( 08 ) , OUT_RESULTADO VARCHAR( 1 ) ) Returning VARCHAR( 1 ) ; -- Declaracoes de variaveis DEFINE vcCod VARCHAR( 15 ) ; DEFINE vcLocal VARCHAR( 02 ) ; DEFINE vnRecno INTEGER ; DEFINE vnQSALDOATU FLOAT ; DEFINE vnCUSTOATU FLOAT ; DEFINE vnCUSTOATU2 FLOAT ; DEFINE vnCUSTOATU3 FLOAT ; DEFINE vnCUSTOATU4 FLOAT ; DEFINE vnCUSTOATU5 FLOAT ; DEFINE vnQTSEGUM FLOAT ; DEFINE vcFil_SB2 VARCHAR( 02 ) ; DEFINE vcFil_SC2 VARCHAR( 02 ) ; DEFINE vnRec INTEGER ; DEFINE vnRecAnt INTEGER ; DEFINE vnMaxRecnoSC2 INTEGER ; DEFINE vcFILAUX VARCHAR( 02 ) ; BEGIN LET OUT_RESULTADO = '0' ; LET vcFILAUX = IN_CFILAUX ; IF vcFILAUX is null THEN LET vcFILAUX = ' ' ; END IF; IF SUBSTR ( IN_XFILIAL , 7 , 1 ) = 'C' THEN LET vcFil_SB2 = ' ' ; ELSE LET vcFil_SB2 = IN_FILIALCOR ; END IF; IF SUBSTR ( IN_XFILIAL , 8 , 1 ) = 'C' THEN LET vcFil_SC2 = ' ' ; ELSE LET vcFil_SC2 = IN_FILIALCOR ; END IF; FOREACH CUR_A330INI WITH HOLD FOR SELECT B2_COD , B2_LOCAL , R_E_C_N_O_ INTO vcCod , vcLocal , vnRecno FROM SB2990 WHERE B2_FILIAL = vcFil_SB2 and B2_COD not like 'MOD%' and D_E_L_E_T_ <> '*' CALL MTXFUN1_99 (IN_XFILIAL , vcCod , vcLocal , IN_DINICIO , vcFILAUX , IN_MV_LOCPROC , IN_FILIALCOR , IN_USER_LG , IN_DATABASE , vnQSALDOATU , vnCUSTOATU , vnCUSTOATU2 , vnCUSTOATU3 , vnCUSTOATU4 , vnCUSTOATU5 , vnQTSEGUM ) RETURNING vnQSALDOATU, vnCUSTOATU, vnCUSTOATU2, vnCUSTOATU3, vnCUSTOATU4, vnCUSTOATU5, vnQTSEGUM; IF vnQSALDOATU > 0 THEN UPDATE SB2990 SET B2_QFIM = vnQSALDOATU , B2_VFIM1 = vnCUSTOATU , B2_VFIM2 = vnCUSTOATU2 , B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 = vnCUSTOATU4 , B2_VFIM5 = vnCUSTOATU5 , B2_CM1 = vnCUSTOATU / vnQSALDOATU , B2_CM2 = vnCUSTOATU2 / vnQSALDOATU , B2_CM3 = vnCUSTOATU3 / vnQSALDOATU , B2_CM4 = vnCUSTOATU4 / vnQSALDOATU , B2_CM5 =

Page 44: SQL Protheus

Programação SQL com SIGA Advanced / AP5

vnCUSTOATU5 / vnQSALDOATU WHERE R_E_C_N_O_ = vnRecno ; ELSE UPDATE SB2990 SET B2_QFIM = vnQSALDOATU , B2_VFIM1 = vnCUSTOATU , B2_VFIM2 = vnCUSTOATU2 , B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 = vnCUSTOATU4 , B2_VFIM5 = vnCUSTOATU5 WHERE R_E_C_N_O_ = vnRecno ; END IF; CONTINUE FOREACH; END FOREACH; SELECT MAX ( R_E_C_N_O_ ) INTO vnMaxRecnoSC2 FROM SC2990 WHERE C2_FILIAL = vcFil_SC2 ; IF vnMaxRecnoSC2 is null THEN LET vnMaxRecnoSC2 = 0 ; END IF; LET vnRec = 0 ; WHILE (vnRec <= vnMaxRecnoSC2 ) LET vnRecAnt = vnRec ; LET vnRec = vnRec + 1024 ; UPDATE SC2990 SET C2_VFIM1 = C2_VINI1 , C2_VFIM2 = C2_VINI2 , C2_VFIM3 = C2_VINI3 , C2_VFIM4 = C2_VINI4 , C2_VFIM5 = C2_VINI5 , C2_APRFIM1 = C2_APRINI1 , C2_APRFIM2 = C2_APRINI2 , C2_APRFIM3 = C2_APRINI3 , C2_APRFIM4 = C2_APRINI4 , C2_APRFIM5 = C2_APRINI5 WHERE R_E_C_N_O_ > vnRecAnt and R_E_C_N_O_ <= vnRec and C2_FILIAL = vcFil_SC2 ; END WHILE LET OUT_RESULTADO = '1' ; Return OUT_RESULTADO; ENDEND PROCEDURE;

4.4. Comandos DDL

São comandos do Administrador do Banco de dados, alguns destes comandos são muito comuns no seu uso e são padronizados em todos os Bancos de Dados, em algum momento eles serão muito úteis.

4.4.1.1. Truncate Table

Comando para remover todos as linhas de uma tabela sem utilizar a opção de log do banco de dados esta função é similar ao conhecido ZAP no Clipper ou um Open output no Cobol.

Exemplo: TRUNCATE TABLE SA1990

4.4.1.2. Drop Table

Remove a tabela do Banco de Dados e todos as suas dependências.

Exemplo: DROP TABLE SA1990


Top Related