Microsiga - Programacao SQL Avancado
Short Description
Download Microsiga - Programacao SQL Avancado...
Description
Programação SQL com SIGA Advanced / AP5
Programação SQL (Avançado)
Com SigaAdvanced/ AP5
Banco de Dados Oracle é a marca registrada da Oracle Corporation. Banco de Dados MSSQL Server é a marca registrada da Microsoft. Banco de Dados Informix é a marca registrada da Informix Corporation. Banco de Dados Sybase é a marca registrada da Sybase Corporation. Banco de Dados UDB é a marca registrada da IBM. Este material é de efeito didático/suporte e não pode ser reproduzido sem autorização da MicroSiga.
Programação SQL com SIGA Advanced / AP5
CopyRight © 2000 Microsiga Software S.A.
Índice 1. Structure Query Language (SQL) 1.1. Introdução 1.2. SELECT 1.3. Clausula WHERE 1.4. INSERT 1.5. UPDATE 1.6. DELETE 1.7. Funções de Agregação 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. Função de String ( SUBSTRING/SUBSTR ) 1.9. ORDER BY 1.10. JOINS 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. Query’s 2.2. Função ChangeQuery 2.3. Stored Procedures 2.4. Comandos DDL 2.4.1. Truncate Table 2.4.2. Drop Table
Programação SQL com SIGA Advanced / AP5
3. Structure Query Language (SQL) 3.1. Introdução
Neste capítulo iremos estudar as sintaxes básicas da linguagem SQL, mostraremos exemplos e executando exercícios práticos. Você vai perceber que a linguagem SQL é sempre em comandos comandos textos que são enviados ao servidor, este fará a compilação e execução da query. Este processo é feito a cada requisição ao servidor. Você perceberá que quanto menos solicitações melhor a performance obtida. Existem vários comandos de manipulação do banco de dados como criação de tabela, tabela, índices, constraints, defaults, etc. Neste curso não estaremos comentando estes comandos, pois os mesmos dependem exclusivamente da plataforma e são de responsabilidade e conhecimento de um DBA. D BA. Indiretamente estas operações são executadas pelo TopConnect em comandos TC’s. Querendo utilizar utili zar uma destas funções, consulte o manual do banco de dados ou procure a orientação de um DBA. Ferramentas de trabalho para os Banco de Dados mais comuns MSSQL Server (isql/w , Query Analyzer), Oracle (WorkSheet) e Informix (SQL Editor) . Estas ferramentas são muito similares a editores de texto, ou seja, você deve digitar todo o comando, e o mesmo será submetido imediatamente ao SGDB.
A seguir estaremos apresentando a sintaxe da linguagem SQL.
Programação SQL com SIGA Advanced / AP5
3.2.
SELECT
Este comando recupera informações gravadas no banco de dados. A diferença básica de um select para um programa orientado a registros é que em um select você pode recuperar várias linhas para uma determinada condição, ao contrário do programa que teria que efetuar vários acessos para obter o mesmo resultado. Ex. se você escrever um programa padrão ADVPL você terá que posicionar o registro, registro, fazer um laço até o final do arquivo, lendo o próximo registro, etc. Veja agora como fazer em linguagem SQL. Sintaxe: SELECT [.] [], Retorno>], n... FROM [], n ...
=> Informar o nome(s) da(s) coluna(s) da(s) tabela(s) que você
deseja apresentar/manipular em seu aplicativo. Se você informar o símbolo ‘*’ (Asterisco) o comando assumirá todas as colunas da tabela. 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).
=> sinônimo utilizado para referenciar uma
tabela correspondente.
=> Será o nome da coluna apresentado para sua aplicação como o
nome original de resultado da query. Ex. Select simples SELECT * FROM SA1990
SELECT A1_COD, A1_NOME FROM SA1990
Quando utilizamos ‘*’ o SGDB estará retornando todas as colunas da tabela, recomendamos sempre informar as colunas que realmente você estará utilizando, por que, se a tabela possuir muitas colunas o tempo de resposta do seu select pode ser mais demorado. Ex. Select com colunas compostas [ +, -, *, /, (, ) ] SELECT C6_QTDVEN * C6_PRCVEN VALOR FROM SC6990
Para colunas do tipo numérico podemos fazer qualquer tipo de cálculo, lembrando que para o cálculo seräo considerados os operadores que estiverem dentro de parênteses para depois consideram os externos e assim por diante. Vale a pena lembrar que no banco de dados os campos numéricos säo do tipo float, portanto näo possuem limitaçäo de casas decimais. No momento de utilizar o resultado devemos efetuar o arredondamento dos dados com a funçäo abaixo: Sintaxe: ROUND(Coluna,Precisão)
Programação SQL com SIGA Advanced / AP5
SELECT round(round(C6_QTDVEN,4)*round(C6_PRCVEN,2),2)VALOR FROM SC6990
Ex. Select com uso de apelido nas colunas SELECT A1_COD CODIGO, A1_NOME NOME, R_E_C_N_O_ RECNO FROM SA1990
Neste caso percebemos que na frente de cada nome de coluna existe um outro nome referenciando a respectiva tabela que chamamos de apelido. Este nome será utilizado como referência referência na resposta resposta da query. Ex. Select com uso de apelido nas tabelas SELECT SA1.A1_COD, SA1.A1_NOME FROM SA1990 SA1 SELECT SA1.A1_COD CODIGO, SA1.A1_NOME NOME, SC5.C5_NUM NUM FROM SA1990 SA1, SC5990 SC5
Agora temos um exemplo de utilização de mais de uma tabela, para referenciarmos a vários campos Ex. Select com uso de múltiplas tabelas com seleção de todas as colunas de uma tabela, e apenas algumas de outra tabela SELECT SA1.*, SC5.C5_NUM NUM FROM SA1990 SA1, SC5990 SC5
Ex. Select com concatenação de colunas SELECT A1_COD + A1_LOJA CODIGO FROM SA1990
Obs: Para Banco de dados Oracle e Informix utilize dois pipes ‘|’ no lugar de ‘+’. 3.3.
Clausula WHERE
Esta clausula é uma das mais importantes do comando SELECT, pois é a partir dela que filtramos os dados da query. O filtro que estaremos informando é muito parecido com a que utilizamos em uma função indregua(), em ADVPL. Sintaxe: SELECT [.] Coluna> [], Retorno>], n... FROM [], n ... WHERE
- informar uma expressão lógica que estará eliminando as linhas que estiverem dentro do contexto informado. Dentro da condição de filtro você pode utilizar os seguintes operadores operadores :
Programação 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) (não é SQL-92 padrão). (Não menor a) (não é SQL-92 padrão). (Não maior a) (não é SQL-92 padrão). Verdadeiro se ambas expressões forem verdadeiras Verdadeiro se qualquer expressão for verdadeira Verdadeiro se a expressão esta dentro de um determinado intervalo EXISTS Verdadeiro se uma subquery contém alguma linha IN Verdadeiro se o operando é igual a uma das expressões da lista NOT Inverte o valor de qualquer outra expressão boleana LIKE ([ _ ],%) Verdadeiro se a expressão fixa for encontrada. Ex. Select utilizando alguns dos operadores SELECT * FROM SE1990 WHERE E1_FILIAL '01' ' AND 'zzzzzz' AND E1_CLIENTE BETWEEN ' BETWEEN ' ' AND 'zz' AND E1_LOJA 'P%' AND E1_PREFIXO LIKE ' AND 'zzzzzz' AND E1_NUM BETWEEN ' AND E1_VENCREA BETWEEN '20000225' AND '20001231' AND E1_EMISSAO 1
Este exemplo faz a contagem do número de ocorrências de código e loja em duplicidade. A clausula having elimina as ocorrências não duplicadas, ou seja count(*) SA1 AND SC5.C5_CLIENTE = SA1.A1_COD SA1 AND SC5.C5_LOJACLI *= SA1.A1_LOJA SA1 AND SC5.C5_CLIENTE = SA1.A1_COD SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA SA3 AND SA1.A1_VEND *= SA3.A3_COD SA1 AND (+) SC5.C5_CLIENTE = SA1.A1_COD SA1 AND SC5.C5_LOJACLI = SA1.A1_LOJA SA3 AND (+) SA1.A1_VEND = SA3.A3_COD SA1 SC5.C5_CLIENTE = SA1.A1_COD SA1 AND SC5.C5_LOJACLI =* SA1.A1_LOJA SA1 AND SC5.C5_CLIENTE = SA1.A1_COD (+) SA1 AND SC5.C5_CLIENTE = SA1.A1_COD (dbStruct()), >(dbStruct()), ni Local nTotsRec := SE1 ->(RecCount()) //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Ponto de entrada para Filtrar os tipos sem entrar na tela do ³ //³ FINRTIPOS(), localizacao Argentina. ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄ /ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄJose ÄÄÄÄJose Lucas, Localiza‡”es ArgentinaÄÙ IF EXISTBLOCK("F130FILT") 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 Impress„o do Cabe‡alho e Rodap‚ ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ cbtxt cbtxt := "* indica titulo provisorio, P Indica Saldo Parcial" cbcont := 1 li := 80 m_pag := 1 //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ POR MAIS ESTRANHO QUE PARE€A, ESTA FUNCAO DEVE SER CHAMADA AQUI! ³ //³ ³ //³ A fun‡„o SomaAbat SomaAbat reabre o SE1 com outro outro nome pela ChkFile para ³ //³ efeito de performance. Se o alias auxil iar para a SumAbat() n„o ³ //³ estiver aberto antes da da IndRegua, ocorre ocorre Erro de & na 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 // mv_par22 // Todas as filiais cFilAte:= mv_par23
Programação SQL com SIGA Advanced / AP5
Endif dbSelectArea("SM0") dbSeek(cEmpAnt+cFilDe,.T.) While !Eof() .and. M0_CODIGO == cEmpAnt .and. M0_CODFIL M0_CODFIL Set Softseek On If mv_par19 == 1
Else
titulo := titulo titulo + OemToAnsi(STR0026) OemToAnsi(STR0026) //" - Analitico"
titulo := titulo titulo + OemToAnsi(STR0027) OemToAnsi(STR0027) //" - Sintetico" cabec1 := OemToAnsi(STR0044) //" Titulos Vencidos | Titulos a Vencer | Vlr.juros ou (Vencidos+Vencer)" (Vencidos+Vencer)" cabec2 := OemToAnsi(STR0045) //" Nominal Valor Corrigido | Valor Nominal | permanencia " EndIf
| | Valor
#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_ D_E_L_E_T_ '*' " endif #ENDIF
IF nOrdem = 1 cChaveSe1 := "E1_FILIAL+E1_NOMCLI+E1_CLIE "E1_FILIAL+E1_NOMCLI+E1_CLIENTE+E1_LOJA+E NTE+E1_LOJA+E1_PREFIXO+E1_NU 1_PREFIXO+E1_NUM+E1_PARCE M+E1_PARCELA+E1_TIPO" LA+E1_TIPO" #IFDEF TOP if TcSrvType() == "AS/400" cIndexSe1 := CriaTrab(nil,.f.) IndRegua("SE1",cIndexSe1,cChaveSe1,,Fr130IndR(),"Selecionando IndRegua("SE1",cIndexSe1,cChaveS e1,,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 IndRegua("SE1",cIndexSe1,cChaveS e1,,Fr130IndR(),"Selecionando Registros...") nIndexSE1 := RetIndex("SE1") dbSetIndex(cIndexSe1+OrdBagExt()) dbSetOrder(nIndexSe1+1) dbSeek(xFilial("SE1")) #ENDIF
cCond1 := "E1_CLIENTE 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 Desconsidera caso saldo seja menor menor ou igual igual a zero ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ If nSaldo E1_CLIENTE+SE1->E1_LOJA) dbSelectArea("SA6") MSSeek(cFilial+SE1->E1_PORTADO) dbSelectArea("SE1") IF li > 58 EndIF EndIF
cabec(titulo,cabec1,cabec2,nomep cabec(titulo,cabec1,cabec2,nomeprog,tamanho,GetM rog,tamanho,GetMv("MV_COMP") v("MV_COMP")))
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 SE 1->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
Programação 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)
Else
>E1_EMISSAO)
Endif nTotJur += nJuros nMesTitj += nJuros nTotFilJ += nJuros
//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) Else >E1_EMISSAO)
nMesTit3 += (nSaldo -nTotAbat) nMesTit4 += (nSaldo -nTotAbat) 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)
Endif
Endif
nMesTit3 -= (nSaldo-nTotAbat) nMesTit4 -= (nSaldo-nTotAbat)
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 E1_HIST,1,20)+ ; IIF(E1_TIPO=="PR IIF(E1_TIPO=="PR ","*"," ")+ ; Iif(nSaldo == xMoeda(E1_VALOR,E1_MOEDA,m xMoeda(E1_VALOR,E1_MOEDA,mv_par15,dDataReaj) v_par15,dDataReaj)," ," ","P") EndIf
Enddo
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ 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
IF nTit5 > 0 .and. nOrdem != 2 SubTot130(nTit0,nTit1,nTit2,nTit3,nTit4, SubTot130(nTit0,nTit1,nTit2,nTit3,nTit4,nOrdem,cCarAnt nOrdem,cCarAnt,nTotJur) ,nTotJur) If mv_par19 == 1 Li++ EndIf Endif //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Verifica quebra por mˆs ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ lQuebra := .F. If nOrdem == 4 .and. Month(SE1 ->E1_VENCREA) >E1_VENCREA) # Month(dDataAnt) Month(dDataAnt) lQuebra := .T. Elseif nOrdem == 6 .and. Month(SE1 ->E1_EMISSAO) >E1_EMISSAO) # Month(dDataAnt) Month(dDataAnt) lQuebra := .T. Endif If lQuebra .and. nMesTTit # 0 ImpMes130(nMesTit0,nMesTit1,nM ImpMes130(nMesTit0,nMesTit1,nMesTit2,nMesTit3, esTit2,nMesTit3,nMesTit4,nMesTTit nMesTit4,nMesTTit,nMesTitJ) ,nMesTitJ) nMesTit1 := nMesTit2 := nMesTit3 := nMesTit4 := nMesTTit := nMesTitj := 0 Endif nTot0+=nTit0 nTot1+=nTit1 nTot2+=nTit2 nTot3+=nTit3 nTot4+=nTit4 nTotJ+=nTotJur
Enddo
nTotFil0+=nTit0 nTotFil1+=nTit1 nTotFil2+=nTit2 nTotFil3+=nTit3 nTotFil4+=nTit4 Store 0 To nTit0,nTit1,nTit2,nTit3,nTit4,nTit5,nTotJur nTit0,nTit1,nTit2,nTit3,nTit4,nTit5,nTotJur,nTotAbat ,nTotAbat
dbSelectArea("SE1")
// voltar para alias existente, se nao, nao funciona
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Imprimir TOTAL por filial somente quan -³
Programação SQL com SIGA Advanced / AP5
//³ do houver mais do que 1 filial. ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ if mv_par21 == 1 .and. SM0 ->(Reccount()) > 1 ImpFil130(nTotFil0,nTotFil1,nTotFil2,nTotFil3,nTotFil4,nTotFiltit,nTotFilJ) Endif Store 0 To nTotFil0,nTotFil1,nTotFil2,n nTotFil0,nTotFil1,nTotFil2,nTotFil3,nTotFil4,nTotFilTit,nTot TotFil3,nTotFil4,nTotFilTit,nTotFilJ FilJ If Empty(xFilial("SE1")) Empty(xFilial("SE1")) Exit Endif #IFDEF TOP if TcSrvType() != "AS/400" dbSelectArea("SE1") dbCloseArea() ChKFile("SE1") dbSelectArea("SE1") dbSelectArea("SE1") dbSetOrder(1) endif #ENDIF
Enddo IF li != 80
EndIF
dbSelectArea("SM0") dbSkip()
IF li > 58
cabec(titulo,cabec1,cabec2,nomepr cabec(titulo,cabec1,cabec2,nomeprog,tamanho,GetM og,tamanho,GetMv("MV_COMP")) v("MV_COMP")) EndIF TotGer130(nTot0,nTot1,nTot2,nTot3,nTot4 TotGer130(nTot0,nTot1,nTot2,nTot3,nTot4,nTotTit,nTotJ) ,nTotTit,nTotJ) Roda(cbcont,cbtxt,"G")
Set Device To Screen #IFNDEF TOP dbSelectArea("SE1") dbClearFil(NIL) RetIndex( "SE1" ) If !Empty(cIndexSE1) FErase (cIndexSE1+OrdBagExt() (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( (cIndexSE1+OrdBagExt()) )) Endif dbSetOrder(1) endif #ENDIF
If aReturn[5] = 1 Set Printer TO dbCommitAll() Ourspool(wnrel) Endif MS_FLUSH() Return
Programação SQL com SIGA Advanced / AP5
Parte do Programa RDMAKE para execução de Query’s
//³Funcao ³ R170IMP //³Descricao ³ Chamada do Relatorio //³ Uso ³ MATR170 Function 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 MV_PAR01 +"' AND E2_NATUREZ E2_NATUREZ = '"+DTOS(mv_par03)+"' '"+DTOS(mv_par03)+"' AND E2_VENCREA = '"+DTOS(mv_par09)+"' '"+DTOS(mv_par09)+"' AND E2_EMISSAO 56 End
cabec(titulo,cabec1,cabec2,nomep cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1) rog,tamanho,1)
_cNatur :=TRB:=TRB ->E2_NATUREZ
dbSelectArea("SED") dbSetOrder(1) dbSeek(xFilial() + _cNatur) _cDescNat := SED ->ED_DESCRIC li := li + 1 @ li, 001 PSAY "Natureza..: "Natureza..: "+AllTrim(_cNatur) "+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. .And. ; IncRegua()
TRB->E2_NATUREZ == _cNatur
Programação SQL com SIGA Advanced / AP5
IF !Empty(TRB->E2_BAIXA) .and. TRB ->E2_BAIXA E2_SALDO == 0 dbSkip() Loop EndIF nAbatimentos:= nAbatimentos:= 0 _nTotAbat := 0 nSaldo := 0 _nSaldoT := 0 _nTotAbat:= nAbatimentos // ----------------------------------------------- Calcula o Saldo ----------------------// ----------------------// fSaldoTit() _nSaldoT := nSaldo _nValor := _nSaldoT - _nTotAbat //------------------------- //-------------------------------------------------------------------// ----------// If _nValor 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))E2_VENCREA))E2_VENCREA)) >E2_VENCREA)) Picture"@R 999" _nTotDia := _nTotDia + _nValor dbSkip() li := li + 1 If li >56 cabec(titulo,cabec1,cabec2,nome cabec(titulo,cabec1,cabec2,nomeprog,tamanho,1) prog,tamanho,1) li := li + 1 @ li, 001 PSAY "Natureza..: "Natureza..: "+AllTrim(_cNatur) "+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 _nTotDia Picture"@E 9,999,999.99" 9,999,999.99" li := li + 2 _nTotNat := _nTotNat + _nTotDia Endif End li := li + 3 @ li, 010 PSAY "Tot.Natureza " + AllTrim(_cNatur) + " - " + AllTrim(_cDescNat) 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"
Programação SQL com SIGA Advanced / AP5
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()
Programação SQL com SIGA Advanced / AP5
4.2.
Função ChangeQuery , SQLOrder e RetSQLName
A função Changequery deve sempre ser executada antes de enviar uma query ao servidor, esta função tem tem como objetivo retornar a query modificada de acordo a melhorar forma possível de escrita para cada banco de dados, portanto para ela ser utilizada você deve utilizar o padrão ANSI de escrita, para depois a função ChangeQuery colocar o código específico de cada Banco de Dados. A Função SQLOrder tem o objetivo de retornar uma cha ve de índice de uma determinada tabela no formato padrão para para a utilização da clausula Order By, ou seja, o retorno da função indexkey(), retorno um chave por exemplo igual a (E1_FILIAL+E1_PREFIXO+E1_NUM+...), após execução desta função ele modifica para (E1_FILIAL,E1_PREFIXO,E1_NUM,...) para campos que contituem funções DTOS e STR também serão ajustados. A função RetSQLName tem o objetivo de retornar o nome da tabela que se encontra na tabela SX2. 4.3.
Stored Procedures
Função do Programa fonte 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"), 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: aSaldoIni[07],cProduto:="",cLocal:="" ="" LOCAL aSaldoFF[05]
… Continuação da função padrão para quando não houver Stored Procedure
Programação SQL com SIGA Advanced / AP5
-- SQLParse - Microsiga Software SA -- Processado em 19/4/2000 09:36:15 -- Dialeto: MSSql 6.5 6.5 --------------------------------------
-- Criacao de procedure CREATE PROCEDURE A330INI_99 ( @IN_XFILIAL VARCHAR( 255 ) , @IN_DINICIO @IN_DINICIO VARCHAR( 8 ) , @IN_CFILAUX VARCHAR( 02 ) , @IN_MV_LOCPROC @IN_MV_LOCPROC VARCHAR( 02 ) , @IN_FILIALCOR @IN_FILIALCOR VARCHAR( 02 ) , @IN_USER_LG VARCHAR( VARCHAR( 17 ) , @IN_DATABASE @IN_DATABASE VARCHAR( 08 ) , @OUT_RESULTADO @OUT_RESULTADO VARCHAR( 1 ) output ) WITH ENCRYPTION ENCRYPTION AS
-- Declaracoes de variaveis DECLARE @cCod @cCod VARCHAR( 15 ) DECLARE @cLocal @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 @cFil_SB2 VARCHAR( 02 02 ) DECLARE @cFil_SC2 @cFil_SC2 VARCHAR( 02 ) DECLARE @nRec INTEGER DECLARE @nRecAnt INTEGER DECLARE @nMaxRecnoSC2 @nMaxRecnoSC2 INTEGER DECLARE @cFILAUX @cFILAUX VARCHAR( 02 ) BEGIN SELECT @OUT_RESULTADO @OUT_RESULTADO = '0' SELECT @cFILAUX @cFILAUX = @IN_CFILAUX @IN_CFILAUX IF @cFILAUX is null BEGIN SELECT @cFILAUX = ' ' END IF SUBSTRING ( @IN_XFILIAL @IN_XFILIAL , 7 , 1 ) = 'C' BEGIN SELECT @cFil_SB2 = ' ' END ELSE BEGIN SELECT @cFil_SB2 @cFil_SB2 = @IN_FILIALCOR @IN_FILIALCOR END IF SUBSTRING ( @IN_XFILIAL @IN_XFILIAL , 8 , 1 ) = 'C' BEGIN SELECT @cFil_SC2 = ' ' END ELSE BEGIN SELECT @cFil_SC2 @cFil_SC2 = @IN_FILIALCOR @IN_FILIALCOR END -- Declaracao do cursor CUR_A330INI DECLARE CUR_A330INI CUR_A330INI INSENSITIVE INSENSITIVE CURSOR FOR SELECT B2_COD , B2_LOCAL , R_E_C_N_O_ FROM SB2990 WHERE B2_FILIAL = @cFil_SB2 @cFil_SB2 and B2_COD B2_COD not like 'MOD%' 'MOD%' and D_E_L_E_T_ D_E_L_E_T_ '*' FOR READ ONLY OPEN CUR_A330INI FETCH CUR_A330INI INTO @cCod , @cLocal , @nRecno WHILE ( (@@fetch_status (@@fetch_statu s = 0 ) ) BEGIN
Programação SQL com SIGA Advanced / AP5
EXEC MTXFUN1_99 @IN_XFILIAL , @cCod , @cLocal , @IN_DINICIO , @cFILAUX , @IN_MV_LOCPROC , @IN_FILIALCOR , @IN_USER_LG , @IN_DATABASE @IN_DATABASE , @nQSALDOATU output , @nCUSTOATU output , @nCUSTOATU2 output , @nCUSTOATU3 output , @nCUSTOATU4 output , @nCUSTOATU5 output , @nQTSEGUM output IF @nQSALDOATU @nQSALDOATU > 0 BEGIN UPDATE SB2990 SET B2_QFIM = @nQSALDOATU @nQSALDOATU , B2_VFIM1 B2_VFIM1 = @nCUSTOATU @nCUSTOATU , B2_VFIM2 B2_VFIM2 = @nCUSTOATU2 @nCUSTOATU2 , B2_VFIM3 B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 B2_VFIM5 = @nCUSTOATU5 @nCUSTOATU5 , B2_CM1 = @nCUSTOATU @nCUSTOATU / @nQSALDOATU @nQSALDOATU , B2_CM2 = @nCUSTOATU2 @nCUSTOATU2 / @nQSALDOATU , B2_CM3 = @nCUSTOATU3 @nCUSTOATU3 / @nQSALDOATU @nQSALDOATU , B2_CM4 B2_CM4 = @nCUSTOATU4 @nCUSTOATU4 / @nQSALDOATU @nQSALDOATU , B2_CM5 = @nCUSTOATU5 @nCUSTOATU5 / @nQSALDOATU @nQSALDOATU WHERE R_E_C_N_O_ R_E_C_N_O_ = @nRecno END ELSE BEGIN UPDATE SB2990 SET B2_QFIM = @nQSALDOATU @nQSALDOATU , B2_VFIM1 B2_VFIM1 = @nCUSTOATU @nCUSTOATU , B2_VFIM2 B2_VFIM2 = @nCUSTOATU2 @nCUSTOATU2 , B2_VFIM3 B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 B2_VFIM5 = @nCUSTOATU5 @nCUSTOATU5 WHERE R_E_C_N_O_ 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 C2_FILIAL = @cFil_SC2 IF @nMaxRecnoSC2 is null BEGIN SELECT @nMaxRecnoSC2 @nMaxRecnoSC2 = 0 END SELECT @nRec = 0 WHILE (@nRec @nRecAnt @nRecAnt and R_E_C_N_O_ 0 BEGIN UPDATE SB2990 WITH (ROWLOCK) SET B2_QFIM = @nQSALDOATU @nQSALDOATU , B2_VFIM1 B2_VFIM1 = @nCUSTOATU @nCUSTOATU , B2_VFIM2 B2_VFIM2 = @nCUSTOATU2 @nCUSTOATU2 , B2_VFIM3 B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 B2_VFIM5 = @nCUSTOATU5 @nCUSTOATU5 , B2_CM1 = @nCUSTOATU @nCUSTOATU / @nQSALDOATU @nQSALDOATU , B2_CM2 = @nCUSTOATU2 @nCUSTOATU2 / @nQSALDOATU , B2_CM3 = @nCUSTOATU3 @nCUSTOATU3 / @nQSALDOATU @nQSALDOATU , B2_CM4 B2_CM4 = @nCUSTOATU4 @nCUSTOATU4 / @nQSALDOATU @nQSALDOATU , B2_CM5 = @nCUSTOATU5 @nCUSTOATU5 / @nQSALDOATU @nQSALDOATU WHERE R_E_C_N_O_ R_E_C_N_O_ = @nRecno END ELSE BEGIN UPDATE SB2990 WITH (ROWLOCK) SET B2_QFIM = @nQSALDOATU @nQSALDOATU , B2_VFIM1 B2_VFIM1 = @nCUSTOATU @nCUSTOATU , B2_VFIM2 B2_VFIM2 = @nCUSTOATU2 @nCUSTOATU2 , B2_VFIM3 B2_VFIM3 = @nCUSTOATU3 , B2_VFIM4 = @nCUSTOATU4 , B2_VFIM5 B2_VFIM5 = @nCUSTOATU5 @nCUSTOATU5 WHERE R_E_C_N_O_ 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 C2_FILIAL = @cFil_SC2 IF @nMaxRecnoSC2 is null BEGIN SET @nMaxRecnoSC2 @nMaxRecnoSC 2 = 0 END SET @nRec @nRec = 0 WHILE (@nRec @nRecAnt @nRecAnt and R_E_C_N_O_ R_E_C_N_O_ 0 THEN
Programação SQL com SIGA Advanced / AP5
UPDATE SB2990 SET B2_QFIM B2_QFIM = vnQSALDOATU vnQSALDOATU , B2_VFIM1 = vnCUSTOATU vnCUSTOATU , B2_VFIM2 = vnCUSTOATU2 vnCUSTOATU2 , B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 B2_VFIM4 = vnCUSTOATU4 , B2_VFIM5 B2_VFIM5 = vnCUSTOATU5 vnCUSTOATU5 , B2_CM1 B2_CM1 = vnCUSTOATU vnCUSTOATU / vnQSALDOATU vnQSALDOATU , B2_CM2 B2_CM2 = vnCUSTOATU2 vnCUSTOATU2 / vnQSALDOATU , B2_CM3 = vnCUSTOATU3 vnCUSTOATU3 / vnQSALDOATU vnQSALDOATU , B2_CM4 B2_CM4 = vnCUSTOATU4 vnCUSTOATU4 / vnQSALDOATU vnQSALDOATU , B2_CM5 B2_CM5 = vnCUSTOATU5 / vnQSALDOATU vnQSALDOATU WHERE R_E_C_N_O_ R_E_C_N_O_ = vnRecno ; ELSE UPDATE SB2990 SET B2_QFIM B2_QFIM = vnQSALDOATU vnQSALDOATU , B2_VFIM1 = vnCUSTOATU vnCUSTOATU , B2_VFIM2 = vnCUSTOATU2 vnCUSTOATU2 , B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 B2_VFIM4 = vnCUSTOATU4 , B2_VFIM5 B2_VFIM5 = vnCUSTOATU5 vnCUSTOATU5 WHERE R_E_C_N_O_ 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 C2_FILIAL = vcFil_SC2 ; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; IF vnMaxRecnoSC2 vnMaxRecnoSC2 is null THEN vnMaxRecnoSC2 vnMaxRecnoSC2 := 0 ; END IF; vnRec := 0 ; WHILE (vnRec vnRecAnt vnRecAnt and R_E_C_N_O_ 0 THEN UPDATE SB2990 SET B2_QFIM = vnQSALDOATU vnQSALDOATU , B2_VFIM1 B2_VFIM1 = vnCUSTOATU , B2_VFIM2 B2_VFIM2 = vnCUSTOATU2 vnCUSTOATU2 , B2_VFIM3 B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 = vnCUSTOATU4 vnCUSTOATU4 , B2_VFIM5 B2_VFIM5 = vnCUSTOATU5 vnCUSTOATU5 , B2_CM1 B2_CM1 = vnCUSTOATU vnCUSTOATU / vnQSALDOATU vnQSALDOATU , B2_CM2 B2_CM2 = vnCUSTOATU2 vnCUSTOATU2 / vnQSALDOATU vnQSALDOATU , B2_CM3 B2_CM3 = vnCUSTOATU3 vnCUSTOATU3 / vnQSALDOATU vnQSALDOATU , B2_CM4 B2_CM4 = vnCUSTOATU4 vnCUSTOATU4 / vnQSALDOATU vnQSALDOATU , B2_CM5 B2_CM5 =
Programação SQL com SIGA Advanced / AP5
vnCUSTOATU5 / vnQSALDOATU vnQSALDOATU WHERE R_E_C_N_O_ R_E_C_N_O_ = vnRecno ; ELSE UPDATE SB2990 SET B2_QFIM = vnQSALDOATU vnQSALDOATU , B2_VFIM1 B2_VFIM1 = vnCUSTOATU , B2_VFIM2 B2_VFIM2 = vnCUSTOATU2 vnCUSTOATU2 , B2_VFIM3 B2_VFIM3 = vnCUSTOATU3 , B2_VFIM4 = vnCUSTOATU4 vnCUSTOATU4 , B2_VFIM5 = vnCUSTOATU5 vnCUSTOATU5 WHERE R_E_C_N_O_ R_E_C_N_O_ = vnRecno ; END IF; CONTINUE FOREACH; END FOREACH; SELECT MAX ( R_E_C_N_O_ ) INTO vnMaxRecnoSC2 vnMaxRecnoSC2 FROM SC2990 WHERE C2_FILIAL C2_FILIAL = vcFil_SC2 ; IF vnMaxRecnoSC2 vnMaxRecnoSC2 is null THEN LET vnMaxRecnoSC2 vnMaxRecnoSC2 = 0 ; END IF; LET vnRec = 0 ; WHILE (vnRec vnRecAnt and R_E_C_N_O_
View more...
Comments