Escolar Documentos
Profissional Documentos
Cultura Documentos
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
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.
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.
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.
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_ <> '*'
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)
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' = '*'
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.
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.
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_ <> *
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
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
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
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_ <> *
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
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_ <> '*'
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_ <> '*'
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_ <> '*'
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_ <> '*'
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
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.
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.
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
| | Valor
| | Valor
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
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. ;
>E1_EMISSAO)
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()
:= 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
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()
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
-- 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
--------------------------------------- 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
--------------------------------------- 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
--------------------------------------- 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 =
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