Você está na página 1de 43

Programao SQL com SIGA Advanced / AP5

Programao SQL (Avanado)

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 didtico/suporte e no pode ser reproduzido sem autorizao da MicroSiga.

Programao SQL com SIGA Advanced / AP5 CopyRight 2000 Microsiga Software S.A.

ndice
1. Structure Query Language (SQL) 1.1. Introduo 1.2. SELECT 1.3. Clausula WHERE 1.4. INSERT 1.5. UPDATE 1.6. DELETE 1.7. Funes de Agregao 1.7.1. SUM 1.7.2. COUNT 1.7.3. AVG 1.7.4. MAX 1.7.5. MIN 1.7.6. Group By 1.7.7. Clausula HAVING 1.7.8. Clausula DISTINCT 1.8. Funo de String ( SUBSTRING/SUBSTR ) 1.9. ORDER BY 1.10. JOINS 1.10.1. INNER JOIN 1.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. UNIONS 1.12. SUB SELECTS 1.13. TRIGGERS 1.14. STORED PROCEDURES 1.15. CURSORES 2. Programando SQL em RDMAKES 2.1. Querys 2.2. Funo ChangeQuery 2.3. Stored Procedures 2.4. Comandos DDL 2.4.1. Truncate Table 2.4.2. Drop Table

Programao SQL com SIGA Advanced / AP5

3. Structure Query Language (SQL) 3.1. Introduo Neste captulo iremos estudar as sintaxes bsicas da linguagem SQL, mostraremos exemplos e executando exerccios prticos. Voc vai perceber que a linguagem SQL sempre em comandos textos que so enviados ao servidor, este far a compilao e execuo da query. Este processo feito a cada requisio ao servidor. Voc perceber que quanto menos solicitaes melhor a performance obtida. Existem vrios comandos de manipulao do banco de dados como criao de tabela, ndices, constraints, defaults, etc. Neste curso no estaremos comentando estes comandos, pois os mesmos dependem exclusivamente da plataforma e so de responsabilidade e conhecimento de um DBA. Indiretamente estas operaes so executadas pelo TopConnect em comandos TCs. Querendo utilizar uma destas funes, consulte o manual do banco de dados ou procure a orientao 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 so 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.

Programao SQL com SIGA Advanced / AP5 3.2. SELECT Este comando recupera informaes gravadas no banco de dados. A diferena bsica de um select para um programa orientado a registros que em um select voc pode recuperar vrias linhas para uma determinada condio, ao contrrio do programa que teria que efetuar vrios acessos para obter o mesmo resultado. Ex. se voc escrever um programa padro ADVPL voc ter que posicionar o registro, fazer um lao at o final do arquivo, lendo o prximo 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 smbolo * (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> => sinnimo utilizado para referenciar uma tabela correspondente. <Nome de Retorno> => Ser o nome da coluna apresentado para sua aplicao 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 numrico podemos fazer qualquer tipo de clculo, lembrando que para o clculo sero considerados os operadores que estiverem dentro de parnteses para depois consideram os externos e assim por diante. Vale a pena lembrar que no banco de dados os campos numricos so do tipo float, portanto no possuem limitao de casas decimais. No momento de utilizar o resultado devemos efetuar o arredondamento dos dados com a funo abaixo: Sintaxe: ROUND(Coluna,Preciso)

Programao 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 referncia 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 utilizao de mais de uma tabela, para referenciarmos a vrios campos Ex. Select com uso de mltiplas tabelas com seleo 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 concatenao 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 funo indregua(), em ADVPL. Sintaxe: SELECT [<apelido>.] <Nome da Coluna> [<Nome de Retorno>], n... FROM <Nome da Tabela> [<apelido>], n ... WHERE <Condio de filtro> <Condio de filtro> - informar uma expresso lgica que estar eliminando as linhas que estiverem dentro do contexto informado. Dentro da condio de filtro voc pode utilizar os seguintes operadores :

Programao SQL com SIGA Advanced / AP5 = > < >= <= <> != !< !> AND OR BETWEEN (igualdade) (maior que) (menor que) (maior que ou igual a) (menor que ou igual a) (diferente) (diferente) (no SQL-92 padro). (No menor a) (no SQL-92 padro). (No maior a) (no SQL-92 padro). Verdadeiro se ambas expresses forem verdadeiras Verdadeiro se qualquer expresso for verdadeira Verdadeiro se a expresso esta dentro de um determinado intervalo EXISTS Verdadeiro se uma subquery contm alguma linha IN Verdadeiro se o operando igual a uma das expresses da lista NOT Inverte o valor de qualquer outra expresso boleana LIKE ([ _ ],%) Verdadeiro se a expresso fixa for encontrada. Ex. Select utilizando alguns dos operadores * SE1990 E1_FILIAL = '01' E1_CLIENTE BETWEEN ' ' AND 'zzzzzz' E1_LOJA BETWEEN ' ' AND 'zz' E1_PREFIXO LIKE 'P%' E1_NUM BETWEEN ' ' AND 'zzzzzz' E1_VENCREA BETWEEN '20000225' AND '20001231' E1_EMISSAO <= '20001231' E1_TIPO IN ('DP ','NF ','AB-','NCC','NCD') NOT E1_EMISSAO = '20000401' D_E_L_E_T_ <> '*'

SELECT FROM WHERE AND AND AND AND AND AND AND AND AND Nota: A

clausula where deve sempre compor o mximo possvel de campos que se adequam a uma chave de ndice e o mximo de filtro possvel definido, desta forma as suas querys tero sempre um resposta rpida.

Programao SQL com SIGA Advanced / AP5

3.4.

INSERT Este comando insere uma linha em uma tabela ou viso. A insero feita pelo SigaAdvanced/AP5 se utiliza deste comando. Em um programa ADVPL no necessrio a utilizao deste comando, pois o TopConnect efetua uma srie de controles na operao. Sintaxe: INSERT INTO <Nome da Tabela> | <Nome da Viso> [ ( Coluna 1,Coluna n,... ) VALUES ] ( Contedo_coluna1, Contedo_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 contedo a inserir INSERT INTO SA4990 (' ','000001','TRANSP.AREO', 'STAR', 'AEREA', 'SP', '51706778000151','765-7865',1) Ex. Insert com select e numerao automtica 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: funo isnull do MSSQL Server, para Oracle utilize nvl Nota: Recomendamos sempre informar o nome das colunas que estaro sendo inseridas, pois se optar pela omisso dos nomes, os valores devero ser informados na ordem de criao da tabela.

Programao SQL com SIGA Advanced / AP5

3.5.

UPDATE Comando para fazer alteraes nas informaes gravadas. Estas alteraes podem ser processadas linha a linha ou em bloco, de acordo com a condio de filtro informada. Sintaxe: UPDATE [FROM] <Nome da Tabela> SET <Nome da Coluna> = <expresso> | <valor> WHERE <Condicional de Filtro> Lembre-se que o comando update faz controle transacional implcito, ou seja, enquanto o comando no for executado at o seu final com sucesso o dado no estar confirmado (Commit). Para a execuo do comando o banco utilizar rea de log, portanto se formos executar um update cujo filtro atinja toda a tabela, ser necessrio espao suficiente para alocar a transao na rea de log. Ex. Update padro 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 SA4990 A4_NOME = 'TRANSPORTADORA STAR LTDA' A4_COD = '000001' D_E_L_E_T_ <> '*'

UPDATE SET WHERE AND

Neste caso a alterao 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 clculo

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 clculo. Ex. Update padro de excluso de registro do SigaAdvanced / AP5

UPDATE SA4990 SET D_E_L_E_T_ = * WHERE R_E_C_N_O_ = 10 Neste exemplo o registro excludo para o sistema SigaAdvanced, ou seja, atravs da programao em ADVPL o comando delet() estar executando o update acima, fazendo uma marca no registro, pois a excluso lgica. Alerta: Nunca execute um comando update sem um condicional, desta forma voc estar alterando todos as linhas da tabela e tambm estar correndo o risco de estourar a rea de log do Banco de Dados. (Utilize ferramentas como SDU ou Configurador)

Programao SQL com SIGA Advanced / AP5

3.6.

DELETE Comando para efetuar a excluso fsica da informao. No SigaAdvanced / AP5 apenas o comando pack executa esta instruo. A construo deste comando semelhante ao update, possuindo tambm opo de filtro. Sintaxe: DELETE [FROM] <Nome da Tabela> WHERE <Condicional de Filtro> Lembre-se que o comando delete faz controle transacional implcito, ou seja, enquanto o comando no for executado at o seu final com sucesso o dado no estar confirmado (Commit). Para a execuo do comando o banco utilizar rea de log, portanto se formos executar um delete cujo filtro atinja toda a tabela, ser necessrio espao suficiente para alocar a transao na rea de log. Ex. Delete para excluso fsica de uma linha

DELETE SA4990 WHERE R_E_C_N_O_ = 10 Neste exemplo ser excludo 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 = '000001' = '*'

DELETE SA4990 WHERE A4_COD AND D_E_L_E_T_

Neste caso a excluso 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 operao extremamente rpida, para conhecedores de Cobol, esta operao conhecida como OPEN OUTPUT. Ateno depois desta operao no existe mais como recuperar as linhas da tabela. (Esta operao no utiliza LOG). Alerta: Nunca execute um comando delete sem um condicional, desta forma voc estar excluindo todos as linhas da tabela e tambm estar correndo o risco de estourar a rea de log do Banco de Dados.

Programao SQL com SIGA Advanced / AP5

3.7.

Funes de Agregao O objetivo principal das funes de agregao criar colunas de acumuladores de um determinado agrupamento definido pela clusula group by. Se esta clusula no for informada o retorno ser sempre uma linha. Sintaxe genrica para as funes: SELECT [DISTINCT] [<FUNCAO>( ] <Nome da coluna|*>[)] [ WHERE <Condicional de Filtro por linha> ] [ GROUP BY <Colunas de agrupamento, coluna1, , coluna16> ] [ HAVING <Condio de agrupamento> ] 3.7.1. SUM Esta funo retorna a somatria de uma coluna(s) defina pelo usurio. Ex. Select que retorna o total de saldo de duplicatas de clientes

SELECT SUM(A1_SALDUP) FROM SA1990 WHERE D_E_L_E_T_ <> * Este exemplo retorna o saldo total dos ttulos em aberto eliminando os registros excludos da base de dados. 3.7.2. COUNT Esta funo totaliza o nmero de linhas na tabela, utlizando filtro para tal. Se for informado o nome de uma coluna, a funo contar apenas as linhas que no estiverem com seu contedo nulo.. Ex. Select que retorna o total de linhas da tabela

SELECT COUNT(*) FROM SA1990 WHERE D_E_L_E_T_ <> * Este exemplo retorna o total de linhas no excludas. Ex. Select que retorna o total de linhas da tabela, considerando somente uma coluna SELECT COUNT(A1_FILIAL) FROM SA1990 WHERE D_E_L_E_T_ <> * Este exemplo retorna o total de linhas no excludas. Se houver contedo nulo em alguma linha, esta no ser contada.

Programao SQL com SIGA Advanced / AP5

3.7.3.

AVG Esta funo retorna a mdia aritmtica da coluna informada, filtrando as linhas pela clausula where ou having. Ex. Select para mdia do saldo a receber de cada cliente

SELECT AVG(A1_SALDUP) FROM SA1990 WHERE D_E_L_E_T_ <> * Este exemplo retorna a mdia da coluna A1_SALDUP, no considerando as linhas excludas. 3.7.4. MAX Esta funo retorna o valor mximo 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 prxima seqncia disponvel. Nunca despreze as linhas excludas, por que este nmero sequencial e nico na tabela. 3.7.5. MIN Esta funo retorna o valor mnimo da coluna especificada. Ex. Select do menor valor da data de emisso do pedido MIN(C6_EMISSAO) SC6990 C6_CLI = 123456 D_E_L_E_T_ <> *

SELECT FROM WHERE AND

Este exemplo retorna o menor valor da coluna C6_EMISSAO. 3.7.6. GROUP BY Esta clusula define quais colunas determinam o agrupamento do comando select. Ex. Select para obter valor total de pedidos por cliente e data C6_CLI, C6_LOJA, C6_EMISSAO, SUM(C6_VALOR) TOTAL SC6990 D_E_L_E_T_ <> * BY C6_CLI, C6_LOJA, C6_EMISSAO

SELECT FROM WHERE GROUP

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

Programao SQL com SIGA Advanced / AP5 Ex. Select para obter quantidade de pedidos por cliente C6_CLI, C6_LOJA, COUNT(*) QTD_PED SC6990 D_E_L_E_T_ <> * C6_EMISSAO between 19990101 and 19990630 BY C6_CLI, C6_LOJA

SELECT FROM WHERE AND GROUP

Este exemplo retorna a quantidade de pedidos, agrupando o resultado por cliente e loja, filtrando o resultado por data de emisso. 3.7.7. HAVING Esta clusula tem por finalidade filtrar os dados que esto numa condio de agrupamento. Apesar de ser uma clusula de filtro (semelhante clusula where), ela dependente da clusula group by. Ex. Select para obter cdigos inseridos com duplicidade A1_COD, A1_LOJA, COUNT(*) SA1990 D_E_L_E_T_ <> * BY A1_COD, A1_LOJA COUNT(*) > 1

SELECT FROM WHERE GROUP HAVING

Este exemplo faz a contagem do nmero de ocorrncias de cdigo e loja em duplicidade. A clausula having elimina as ocorrncias no duplicadas, ou seja count(*) <= 1. 3.7.8. DISTINCT Esta clusula elimina repeties 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 CFOs repetidos. Ex. Select para obter cdigo das filiais com linhas existentes (vlido para tabela com X2_MODO = E) SELECT DISTINCT A1_FILIAL FROM SA1990 WHERE D_E_L_E_T_ <> *

Programao SQL com SIGA Advanced / AP5

3.8.

Funo de String ( SUBSTRING/SUBSTR ) Esta funo idntica a funo 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 genrica para as funes: SUBSTR[ING](<Origem>,<n posio inicial>,<tamanho em bytes>) Ex. Select para apresentar parte do nome do cliente para todos os clientes que possuem 5 na segunda posio do cdigo. SELECT FROM WHERE AND SUBSTRING(A1_NOME,1,20) NOME SA1990 SUBSTRING(A1_CODIGO,2,1) = 5 D_E_L_E_T_ <> *

No recomendamos a utilizao da funo na clusula WHERE, pois o banco ter que fazer uma busca em toda a tabela, por no possuir ndice do contedo a ser filtrado. 3.9. ORDER BY Esta clusula 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 clusua ORDER BY as mesmas colunas que compe um ndice j existente no banco de dados, caso contrrio o banco ter que ordernar os dados na rea temporria (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 FROM WHERE ORDER A1_NOME SA1990 D_E_L_E_T_ <> * BY A1_NOME DESC

Ex. Select para apresentar os cliente por ordem de cdigo e loja de forma crescente. SELECT FROM WHERE ORDER A1_COD, A1_LOJA SA1990 D_E_L_E_T_ <> * BY A1_COD, A1_LOJA

Programao SQL com SIGA Advanced / AP5

Note que neste exemplo no necessrio informar a expresso ASC, para obter o resultado de forma crescente. Nota : Em alguns casos de querys voc ir perceber que o resultado j estar apresentando as linhas por uma certa ordenao, isto que dizer que o banco de dados utilizou um ndice para resolver o problema, mas isto no 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 operao uma das mais poderosas expresses de um comando select, pois com ela podemos relacionar tabelas obtendo informaes cruzadas. Este comando pode ser escrito de duas formas, porm alguns bancos suportam apenas uma delas. Estaremos apresentado esta forma e comentaremos suas diferenas. O relacionamento entre as tabelas feito utilizando o smbolo de igualdade entre duas colunas, sendo uma coluna de cada tabela. Lembre-se que o relacionamento feito de forma binria, 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 recomendao devemos sempre tentar relacionar no mximo quatro tabelas, lgico que existe excees, 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 no ser vivel. Existem vrias situaes que dependem de experincia e teste para conseguirmos chegar na melhor soluo possvel. Sempre que utilizarmos joins devemos sempre informar todas as tabelas que sero relacionadas na clausula from e todos os seus relacionamentos na clausula where se por acaso no 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 no foi relacionado com as demais tabelas.Se isto acontecer o servidor poder ter srios 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 FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5, SA1990 SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.C5_CLIENTE = SA1.A1_COD SC5.C5_LOJACLI = SA1.A1_LOJA SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

<= Define o rel.SC5->SA1 <= Define o rel.SC5->SA1

Programao SQL com SIGA Advanced / AP5 Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do Vendedor SELECT FROM WHERE AND AND AND AND AND AND AND 3.10.1.2. SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME SC5990 SC5, SA1990 SA1, SA3990 SA3 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SA3.A3_FILIAL = 01 SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3 SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

LEFT JOIN ou LEFT OUTER JOIN

O resultado de um left join inclui todas as linhas da tabela que foi especfica a esquerda da clausula LEFT OUTER , ou seja, independente de existir ou no um dado relacionado na tabela informada mais a direita da tabela todas as linhas referentes a tabela da esquerda sero retornadas. Nas linhas que no existe um linha de relao com a tabela a direita os campos desta tabela sero retornados com valor nulo. O smbolo ( *= ) representa um LEFT JOIN para o MSSQL Server, Sybase, o campo indicado do lado do smbolo (*) ser o da tabela que voc deseja que todas as linhas sejam retornadas independente da existncia do dado da coluna mais a direita, vamos ver exemplos de querys para estes Bancos de Dados. Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo que no exista o cliente SELECT FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5, SA1990 SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.C5_CLIENTE *= SA1.A1_COD SC5.C5_LOJACLI *= SA1.A1_LOJA SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

<= Define o rel.SC5->SA1 <= Define o rel.SC5->SA1

Ex. Select para retornar todas os pedidos de venda, nome do cliente e o nome do Vendedor mesmo que no exista o Vendedor SELECT FROM WHERE AND AND AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME SC5990 SC5, SA1990 SA1, SA3990 SA3 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SA3.A3_FILIAL = 01 SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 SA1.A1_VEND *= SA3.A3_COD <= Define o rel.SA1->SA3 SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

Programao SQL com SIGA Advanced / AP5 O smbolo (+ ) 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 existncia do dado da coluna mais a direita, vamos ver exemplos de querys para estes Bancos de Dados. Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo que no exista o cliente SELECT FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5, SA1990 SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' (+) SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 (+) SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 SC5.D_E_L_E_T_ <> '*' 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 no exista o Vendedor SELECT FROM WHERE AND AND AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME SC5990 SC5, SA1990 SA1, SA3990 SA3 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SA3.A3_FILIAL = 01 SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 (+) SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1->SA3 SC5.D_E_L_E_T_ <> '*' 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 existncia do dado da coluna mais a direita, vamos ver exemplos de querys para estes Bancos de Dados. Ex. Select para retornar todas os pedidos de venda e o nome do cliente mesmo que no exista o cliente SELECT FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5 OUTER, SA1990 SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 SC5.D_E_L_E_T_ <> '*' 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 no exista o Vendedor SELECT FROM WHERE AND AND SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME SC5990 SC5, SA1990 SA1 OUTER, SA3990 SA3 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SA3.A3_FILIAL = 01

Programao SQL com SIGA Advanced / AP5 AND AND AND AND AND SC5.C5_CLIENTE = SA1.A1_COD SC5.C5_LOJACLI = SA1.A1_LOJA SA1.A1_VEND = SA3.A3_COD SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*' <= Define o rel.SC5->SA1 <= Define o rel.SC5->SA1 <= Define o rel.SA1->SA3

Nota: No possvel 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 especfica a direita da clausula RIGHT OUTER , ou seja, independente de existir ou no um dado relacionado na tabela informada mais a esquerda da tabela todas as linhas referentes a tabela da direita sero retornadas. Nas linhas que no existe um linha de relao com a tabela a direita os campos desta tabela sero retornados com valor nulo. O smbolo ( =* ) representa um RIGHT JOIN para o MSSQL Server, Sybase, o campo indicado do lado do smbolo (*) ser o da tabela que voc deseja que todas as linhas sejam retornadas independente da existncia do dado da coluna mais a esquerda, vamos ver exemplos de querys para estes Bancos de Dados. Ex. Select para retornar todos os clientes mesmo que no exista pedidos relacionados SELECT FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5, SA1990 SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.C5_CLIENTE =* SA1.A1_COD SC5.C5_LOJACLI =* SA1.A1_LOJA SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

<= Define o rel.SC5->SA1 <= Define o rel.SC5->SA1

O smbolo ( + ) representa um RIGHT JOIN para o Oracle, o campo indicado do lado do smbolo (+) ser o da tabela que voc deseja que todas as linhas sejam retornadas independente da existncia do dado da coluna mais a esquerda, vamos ver exemplos de querys para estes Bancos de Dados. Ex. Select para retornar todos os clientes mesmo que no exista pedidos relacionados SELECT FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5, SA1990 SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.C5_CLIENTE = SA1.A1_COD (+) <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA (+) <= Define o rel.SC5->SA1 SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

Programao 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 existncia do dado da coluna mais a esquerda, vamos ver exemplos de querys para estes Bancos de Dados. Ex. Select para retornar todos os clientes mesmo que no exista pedidos relacionados SELECT FROM WHERE AND AND AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5, SA1990 SA1 OUTER SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

Nota: No possvel 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 possveis de relacionamento. Exemplo para o Banco MSSQL Server e Sybase Ex. Select para retornar todos os clientes e todos os pedidos mesmo que no exista pedidos ou clientes relacionados SELECT FROM ON AND WHERE AND AND AND SC5.C5_NUM, SA1.A1_NOME SC5990 SC5 FULL OUTER SA1990 SA1 SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1 SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1 SC5.C5_FILIAL = '01' SA1.A1_FILIAL = ' ' SC5.D_E_L_E_T_ <> '*' SA1.D_E_L_E_T_ <> '*'

Nota: Nos demais Bancos de Dados no 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 soluo tambm para os demais bancos de dados, e at mesmo os que tem a opo. 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 no exista pedidos ou clientes relacionados

Programao SQL com SIGA Advanced / AP5

SELECT SC5.C5_NUM, SA1.A1_NOME FROM SC5990 SC5, SA1990 SA1 Nota: Existem vrios 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 nmero de linhas muito grande ns estaremos consumindo processador e i/o de disco inutilmente. 3.11. UNIONS A expresso UNION permite voc combinar o resultado de dois ou mais SELECTs em um nico resultado. Uma das restries 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 nmero de colunas devem ter tipos de dados compatveis. Ex. Select para retornar todos os clientes da empresa 01 e da empresa 02 desconsiderando duplicidades SELECT FROM UNION SELECT FROM A1_COD, A1_LOJA, A1_NOME SA1990 A1_COD, A1_LOJA, A1_NOME 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 ALL SELECT A1_COD, A1_LOJA, A1_NOME FROM SA1010 Nota: Existem vrios casos de programadores que esquecem de informar a clausula ALL , e acontece um grande problema que parece estar faltando registros de dados nos programas.

Programao SQL com SIGA Advanced / AP5

3.12.

SUB SELECTS

Sub-Selects utilizado na clausula where onde pode ser utilizado para fazer relao de verificao de um determinado dado da tabela original com vrias 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 FROM WHERE AND AND AND AND DISTINCT SA1.A1_NOME SA1990 SA1, SC5990 SC5 SA1.A1_FILIAL = ' ' SC5.C5_FILIAL = '01' SC5.C5_CLIENTE = SA1.A1_COD SC5.C5_LOJACLI = SA1.A1_LOJA 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 FROM WHERE AND AND AND AND DISTINCT SA1.A1_NOME SA1990 SA1, SC5990 SC5 SA1.A1_FILIAL = ' ' SC5.C5_FILIAL = '01' SC5.C5_CLIENTE = SA1.A1_COD SC5.C5_LOJACLI = SA1.A1_LOJA 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 so gatilhos do Banco de Dados, os quais so acionados por uma incluso, alterao ou excluso de uma linha em uma determinada tabela. Cada Banco de Dados trata as triggers de uma forma, hoje o SigaAdvanced/AP5 no utiliza estas triggers. As triggers podem ser utilizadas pelos clientes, considerando o seguinte problema: Se houver qualquer alterao na estrutura de uma tabela o sistema ir reconstruir a tabela mas com sua nova estrutura, ndices, defaults, ..., mas no ir recriar os triggers criados associados a estas tabelas.

Programao SQL com SIGA Advanced / AP5

3.14.

STORED PROCEDURES

Stored Procedures so programas feitos em linguagem nativa do Banco de Dados em questo que no utiliza o padro ANSI/92, uma Stored Procedure pode resolver vrios problemas de performance, por que uma procedure alm de estar sendo executada no prprio Banco de dados que elimina o trfego de rede, ela j foi pr-compilada, ou seja, ela no passa por uma re-compilao a cada vez que ela executada. A Microsiga utiliza vrias Storeds Procedures em processos crticos para clientes com Base de Dados muito grande, em clientes pequenos este processo no se faz necessrio, alm de que clientes menores utilizam servidores menores que nem sempre tem capacidade suficiente para executar SPs. 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 divergncia entre programas fontes. 3.15. CURSORES

Cursores so definies de conjunto de dados que sero manipulados linha a linha, ou seja, da mesma forma que estamos acostumados a fazer uma linguagem posicional onde os registros so tratados um a um. 4. Programando SQL em RDMAKES 4.1. Querys Agora vamos ver um exemplo prtico utilizando query diretamente no Banco de Dados Programa interno do SigaAdvanced/AP5
As linhas em negrito so as modificaes 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 CbCont Local CbTxt Local limite := 220 Local nOrdem Local lContinua := .T. Local cCond1,cCond2,cCarAnt Local nTit0:=0 Local nTit1:=0 Local nTit2:=0 Local nTit3:=0 Local nTit4:=0 Local nTit5:=0 Local nTotJ:=0 Local nTot0:=0 Local nTot1:=0 Local nTot2:=0 Local nTot3:=0 Local nTot4:=0 Local nTotTit:=0 Local nTotJur:=0 Local nTotFil0:=0 Local nTotFil1:=0

Programao SQL com SIGA Advanced / AP5


Local nTotFil2:=0 Local nTotFil3:=0 Local nTotFil4:=0 Local nTotFilTit:=0 Local nTotFilJ:=0 Local aCampos:={} Local aTam:={} Local nAtraso:=0 Local nTotAbat:=0 Local nSaldo:=0 Local dDataReaj Local dDataAnt := dDataBase Local lQuebra Local nMesTit0 := 0 Local nMesTit1 := 0 Local nMesTit2 := 0 Local nMesTit3 := 0 Local nMesTit4 := 0 Local nMesTTit := 0 Local nMesTitj := 0 Local cIndexSe1 Local cChaveSe1 Local nIndexSE1 Local dDtContab Local cTipos := "" Local aStru := SE1->(dbStruct()), ni Local nTotsRec := SE1->(RecCount()) // // Ponto de entrada para Filtrar os tipos sem entrar na tela do // FINRTIPOS(), localizacao Argentina. //Jose Lucas, Localizaes Argentina IF EXISTBLOCK("F130FILT") cTipos := EXECBLOCK("F130FILT",.f.,.f.) ENDIF nOrdem:=aReturn[8] cMoeda:=Str(mv_par15,1) PRIVATE dBaixa := dDataBase PRIVATE cFilDe,cFilAte // // Vari veis utilizadas para Impresso do Cabealho e Rodap // cbtxt := "* indica titulo provisorio, P Indica Saldo Parcial" cbcont := 1 li := 80 m_pag := 1 // // POR MAIS ESTRANHO QUE PAREA, ESTA FUNCAO DEVE SER CHAMADA AQUI! // // A funo SomaAbat reabre o SE1 com outro nome pela ChkFile para // efeito de performance. Se o alias auxiliar para a SumAbat() no // 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 := cFilAnt cFilAte:= cFilAnt ELSE cFilDe := mv_par22 // Todas as filiais cFilAte:= mv_par23

Programao 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_CODFIL Set Softseek On If mv_par19 == 1 titulo := titulo + OemToAnsi(STR0026) //" - Analitico" Else titulo := titulo + OemToAnsi(STR0027) //" - Sintetico" cabec1 := OemToAnsi(STR0044) //" Titulos Vencidos | Titulos a Vencer | Vlr.juros ou (Vencidos+Vencer)" cabec2 := OemToAnsi(STR0045) //" 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 = 1 cChaveSe1 := "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")) #ENDIF cCond1 := "E1_CLIENTE <= mv_par02" cCond2 := "E1_CLIENTE + E1_LOJA" titulo := titulo + OemToAnsi(STR0017) //" - Por Cliente" Elseif nOrdem = 2 SE1->(dbSetOrder(1)) #IFNDEF TOP dbSeek(cFilial+mv_par03+mv_par05) #ELSE if TcSrvType() == "AS/400" dbSeek(cFilial+mv_par03+mv_par05) else cOrder := SqlOrder(IndexKey()) endif #ENDIF cCond1 := "E1_NUM <= mv_par06" cCond2 := "E1_NUM" titulo := titulo + OemToAnsi(STR0018) //" - Por Numero" Elseif nOrdem = 3

| | Valor

Programao SQL com SIGA Advanced / AP5


SE1->(dbSetOrder(4)) #IFNDEF TOP dbSeek(cFilial+mv_par07) #ELSE if TcSrvType() == "AS/400" dbSeek(cFilial+mv_par07) else cOrder := SqlOrder(IndexKey()) endif #ENDIF cCond1 := "E1_PORTADO <= mv_par08" cCond2 := "E1_PORTADO" titulo := titulo + OemToAnsi(STR0019) //" - Por Banco" Elseif nOrdem = 4 SE1->(dbSetOrder(7)) #IFNDEF TOP dbSeek(cFilial+DTOS(mv_par09)) #ELSE if TcSrvType() == "AS/400" dbSeek(cFilial+DTOS(mv_par09)) else cOrder := SqlOrder(IndexKey()) endif #ENDIF cCond1 := "E1_VENCREA <= mv_par10" cCond2 := "E1_VENCREA" titulo := titulo + OemToAnsi(STR0020) //" - Por Data de Vencimento" Elseif nOrdem = 5 SE1->(dbSetOrder(3)) #IFNDEF TOP dbSeek(cFilial+mv_par11) #ELSE if TcSrvType() == "AS/400" dbSeek(cFilial+mv_par11) else cOrder := SqlOrder(IndexKey()) endif #ENDIF cCond1 := "E1_NATUREZ <= mv_par12" cCond2 := "E1_NATUREZ" titulo := titulo + OemToAnsi(STR0021) //" - Por Natureza" Elseif nOrdem = 6 SE1->(dbSetOrder(6)) #IFNDEF TOP dbSeek( cFilial+DTOS(mv_par13)) #ELSE if TcSrvType() == "AS/400" dbSeek( cFilial+DTOS(mv_par13)) else cOrder := SqlOrder(IndexKey()) endif #ENDIF cCond1 := "E1_EMISSAO <= mv_par14" cCond2 := "E1_EMISSAO" titulo := titulo + OemToAnsi(STR0042) //" - Por Emissao" Elseif nOrdem == 7 cChaveSe1 := "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")

Programao SQL com SIGA Advanced / AP5


dbSetOrder(nIndexSe1+1) dbSeek(xFilial("SE1")) else cOrder := SqlOrder(cChaveSe1) endif #ENDIF cCond1 := "E1_VENCREA <= mv_par10" cCond2 := "DtoS(E1_VENCREA)+E1_PORTADO" titulo := titulo + OemToAnsi(STR0023) //" - Por Vencto/Banco" Elseif nOrdem = 8 SE1->(dbSetOrder(2)) #IFNDEF TOP dbSeek(cFilial+mv_par01,.T.) #ELSE if TcSrvType() == "AS/400" dbSeek(cFilial+mv_par01,.T.) else cOrder := SqlOrder(IndexKey()) endif #ENDIF cCond1 := "E1_CLIENTE <= mv_par02" cCond2 := "E1_CLIENTE" titulo := titulo + OemToAnsi(STR0024) //" - Por Cod.Cliente" Elseif nOrdem = 9 cChave := "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")) else cOrder := SqlOrder(cChave) endif #ENDIF cCond1 := "E1_PORTADO <= mv_par08" cCond2 := "E1_PORTADO+E1_SITUACA" titulo := titulo + OemToAnsi(STR0025) //" - Por Banco e Situacao" Endif If mv_par19 == 1 titulo := titulo + OemToAnsi(STR0026) //" - Analitico" Else titulo := titulo + OemToAnsi(STR0027) //" - Sintetico" cabec1 := OemToAnsi(STR0044) //"Nome do Cliente Titulos Vencidos | Titulos a Vencer | Vlr.juros ou (Vencidos+Vencer)" cabec2 := OemToAnsi(STR0045) //" Nominal Valor Corrigido | Valor Nominal | permanencia " EndIf cFilterUser:=aReturn[7] Set Softseek Off #IFDEF TOP if 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 + "'"

| | Valor

Programao 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 == 2 cQuery += ' AND E1_SALDO <> 0' Endif cQuery += " 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 Next endif #ENDIF SetRegua(nTotsRec) While &cCond1 .and. !Eof() .and. lContinua .and. E1_FILIAL == xFilial("SE1") #IFNDEF WINDOWS Inkey() If LastKey() = K_ALT_A lEnd := .t. Endif #ENDIF IF 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 WINDOWS Inkey() 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() lEnd @PROW()+1,001 PSAY OemToAnsi(STR0028) //"CANCELADO PELO OPERADOR" Exit

Programao SQL com SIGA Advanced / AP5

dbSelectArea("SE1") // // Filtrar com base no Pto de entrada do Usuario... //Jose Lucas, Localizaes 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 provisrios // 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 vazio dDtContab := 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. ;

Programao SQL com SIGA Advanced / AP5


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 > dDataBase dbSkip() 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 Base nSaldo :=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 titulo nSaldo-=SomaAbat(SE1->E1_PREFIXO,SE1->E1_NUM,SE1>E1_PARCELA,"R",mv_par15,dDataReaj,SE1->E1_CLIENTE,SE1->E1_LOJA) EndIf nSaldo:=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 > 58 cabec(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 < mv_par05 .OR. SE1->E1_NUM >

Programao SQL com SIGA Advanced / AP5


If mv_par19 == 1 @li, 116 PSAY nSaldo Picture tm ( nSaldo, 14 ) EndIf nJuros:=0 fa070Juros(mv_par15) dbSelectArea("SE1") If mv_par19 == 1 @li,133 PSAY nSaldo+nJuros Picture tm(nSaldo+nJuros,14) EndIf If 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) Else 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) Endif nTotJur += nJuros nMesTitj += nJuros nTotFilJ += nJuros Else //a vencer If mv_par19 == 1 @li,149 PSAY nSaldo Picture tm ( nSaldo, 14 ) EndIf If ! ( SE1->E1_TIPO $ "RA /"+MV_CRNEG) nTit0 += xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1nTit3 += (nSaldo-nTotAbat) nTit4 += (nSaldo-nTotAbat) nMesTit0 += xMoeda(SE1->E1_VALOR,SE1->E1_MOEDA,mv_par15,SE1>E1_EMISSAO) nMesTit3 += (nSaldo-nTotAbat) nMesTit4 += (nSaldo-nTotAbat) Else 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) Endif Endif If mv_par19 == 1 @ li, 166 PSAY SE1->E1_NUMBCO EndIf If nJuros > 0 If mv_par19 == 1 @ Li,177 PSAY nJuros Picture Tm(nJuros,12) EndIf nJuros := 0 Endif IF dDataBase > SE1->E1_VENCREA nAtraso:=dDataBase-SE1->E1_VENCTO IF Dow(SE1->E1_VENCTO) == 1 .Or. Dow(SE1->E1_VENCTO) == 7 IF Dow(dBaixa) == 2 .and. nAtraso <= 2

>E1_EMISSAO)

Programao SQL com SIGA Advanced / AP5


nAtraso := 0 EndIF EndIF nAtraso:=IIF(nAtraso<0,0,nAtraso) IF nAtraso>0 If mv_par19 == 1 @li ,193 PSAY nAtraso Picture "9999" EndIf EndIF EndIF If 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 != 2 SubTot130(nTit0,nTit1,nTit2,nTit3,nTit4,nOrdem,cCarAnt,nTotJur) If mv_par19 == 1 Li++ EndIf Endif // // Verifica quebra por ms // 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. Endif If lQuebra .and. nMesTTit # 0 ImpMes130(nMesTit0,nMesTit1,nMesTit2,nMesTit3,nMesTit4,nMesTTit,nMesTitJ) nMesTit1 := nMesTit2 := nMesTit3 := nMesTit4 := nMesTTit := nMesTitj := 0 Endif nTot0+=nTit0 nTot1+=nTit1 nTot2+=nTit2 nTot3+=nTit3 nTot4+=nTit4 nTotJ+=nTotJur nTotFil0+=nTit0 nTotFil1+=nTit1 nTotFil2+=nTit2 nTotFil3+=nTit3 nTotFil4+=nTit4 Store 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-

Programao 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) Endif Store 0 To nTotFil0,nTotFil1,nTotFil2,nTotFil3,nTotFil4,nTotFilTit,nTotFilJ If Empty(xFilial("SE1")) Exit Endif #IFDEF TOP if TcSrvType() != "AS/400" dbSelectArea("SE1") dbCloseArea() ChKFile("SE1") dbSelectArea("SE1") dbSetOrder(1) endif #ENDIF dbSelectArea("SM0") dbSkip() Enddo IF li != 80 IF li > 58 cabec(titulo,cabec1,cabec2,nomeprog,tamanho,GetMv("MV_COMP")) EndIF TotGer130(nTot0,nTot1,nTot2,nTot3,nTot4,nTotTit,nTotJ) Roda(cbcont,cbtxt,"G") EndIF Set Device To Screen #IFNDEF TOP dbSelectArea("SE1") dbClearFil(NIL) RetIndex( "SE1" ) If !Empty(cIndexSE1) FErase (cIndexSE1+OrdBagExt()) Endif dbSetOrder(1) #ELSE if TcSrvType() != "AS/400" dbSelectArea("SE1") dbCloseArea() ChKFile("SE1") dbSelectArea("SE1") dbSetOrder(1) else dbSelectArea("SE1") dbClearFil(NIL) RetIndex( "SE1" ) If !Empty(cIndexSE1) FErase (cIndexSE1+OrdBagExt()) Endif dbSetOrder(1) endif #ENDIF If aReturn[5] = 1 Set Printer TO dbCommitAll() Ourspool(wnrel) Endif MS_FLUSH() Return

Programao SQL com SIGA Advanced / AP5

Parte do Programa RDMAKE para execuo de Querys //Funcao R170IMP //Descricao Chamada do Relatorio // Uso MATR170 Function R170Imp dbSelectArea("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 New dbSelectArea("TRB") nCont := 0 SetRegua(15000) // // Faz manualmente porque nao chama a funcao Cabec() // _nTotGer := 0 li := 60 cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1) li := 06 While !Eof() IncRegua() If li >56 cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1) End _cNatur :=TRB->E2_NATUREZ dbSelectArea("SED") dbSetOrder(1) dbSeek(xFilial() + _cNatur) _cDescNat := SED->ED_DESCRIC li := li + 1 @ li, 001 PSAY "Natureza..: "+AllTrim(_cNatur) + " - " + _cDescNat li := li + 2 dbSelectArea("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()

Programao SQL com SIGA Advanced / AP5


IF !Empty(TRB->E2_BAIXA) .and. TRB->E2_BAIXA <= DTOS(dDataBase) .and.; TRB->E2_SALDO == 0 dbSkip() Loop EndIF nAbatimentos:= 0 _nTotAbat nSaldo _nSaldoT

:= 0 := 0 := 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 + _nValor dbSkip() li := li + 1 If 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 End If _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 Endif End li := li + 3 @ li, 010 PSAY "Tot.Natureza " + AllTrim(_cNatur) + " - " + AllTrim(_cDescNat) @ li, 064 PSAY _nTotNat Picture"@E 9,999,999.99" _nTotGer := _nTotGer + _nTotNat li := 58 End @ li, 010 PSAY "Total do Relatorio..:" @ li, 062 PSAY _nTotGer Picture"@E 999,999,999.99" EJECT

Programao SQL com SIGA Advanced / AP5

dbSelectArea("TRB") dbCloseArea() RetIndex("SE2") dbSetOrder(1) Set device to Screen If aReturn[5] == 1 Set Printer TO dbcommitAll() ourspool(wnrel) Endif MS_FLUSH() __Return()

Programao SQL com SIGA Advanced / AP5

4.2.

Funo ChangeQuery , SQLOrder e RetSQLName A funo Changequery deve sempre ser executada antes de enviar uma query ao servidor, esta funo tem como objetivo retornar a query modificada de acordo a melhorar forma possvel de escrita para cada banco de dados, portanto para ela ser utilizada voc deve utilizar o padro ANSI de escrita, para depois a funo ChangeQuery colocar o cdigo especfico de cada Banco de Dados. A Funo SQLOrder tem o objetivo de retornar uma chave de ndice de uma determinada tabela no formato padro para a utilizao da clausula Order By, ou seja, o retorno da funo indexkey(), retorno um chave por exemplo igual a (E1_FILIAL+E1_PREFIXO+E1_NUM+...), aps execuo desta funo ele modifica para (E1_FILIAL,E1_PREFIXO,E1_NUM,...) para campos que contituem funes DTOS e STR tambm sero ajustados. A funo RetSQLName tem o objetivo de retornar o nome da tabela que se encontra na tabela SX2.

4.3.

Stored Procedures

Funo 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 TOP Local cXFIlial,aResult IF !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") Endif Else Xa330Inicia() Endif Return Nil Static Function Xa330Inicia() #ENDIF LOCAL nV,nX,bBloco:={ |nV,nX| Trim(nV)+STR(nX,1) } LOCAL aSaldoIni[07],cProduto:="",cLocal:="" LOCAL aSaldoFF[05]

Continuao da funo padro para quando no houver Stored Procedure

Programao 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 variaveis DECLARE @cCod VARCHAR( 15 ) DECLARE @cLocal VARCHAR( 02 ) DECLARE @nRecno INTEGER DECLARE @nQSALDOATU FLOAT DECLARE @nCUSTOATU FLOAT DECLARE @nCUSTOATU2 FLOAT DECLARE @nCUSTOATU3 FLOAT DECLARE @nCUSTOATU4 FLOAT DECLARE @nCUSTOATU5 FLOAT DECLARE @nQTSEGUM FLOAT DECLARE @cFil_SB2 VARCHAR( 02 ) DECLARE @cFil_SC2 VARCHAR( 02 ) DECLARE @nRec INTEGER DECLARE @nRecAnt INTEGER DECLARE @nMaxRecnoSC2 INTEGER DECLARE @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

Programao 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

Programao 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 variaveis DECLARE @cCod VarChar( 15 ) DECLARE @cLocal VarChar( 02 ) DECLARE @nRecno Integer DECLARE @nQSALDOATU Float DECLARE @nCUSTOATU Float DECLARE @nCUSTOATU2 Float DECLARE @nCUSTOATU3 Float DECLARE @nCUSTOATU4 Float DECLARE @nCUSTOATU5 Float DECLARE @nQTSEGUM Float DECLARE @cFil_SB2 VarChar( 02 ) DECLARE @cFil_SC2 VarChar( 02 ) DECLARE @nRec Integer DECLARE @nRecAnt Integer DECLARE @nMaxRecnoSC2 Integer DECLARE @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

Programao 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

Programao 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 variaveis vcCod 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_A330INI CURSOR CUR_A330INI IS SELECT B2_COD , B2_LOCAL , R_E_C_N_O_ FROM SB2990 WHERE 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

Programao 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;

Programao 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 =

Programao 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; END END PROCEDURE;

4.4.

Comandos DDL So comandos do Administrador do Banco de dados, alguns destes comandos so muito comuns no seu uso e so padronizados em todos os Bancos de Dados, em algum momento eles sero muito teis. 4.4.1.1. Truncate Table Comando para remover todos as linhas de uma tabela sem utilizar a opo de log do banco de dados esta funo 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 dependncias. Exemplo: DROP TABLE SA1990

Você também pode gostar