Você está na página 1de 8

O objetivo do Embedded SQL facilitar a escrita e leitura de queries.

Para isso, foi definida


uma sintaxe para que se possa escrever a query diretamente no cdigo AdvPL, sem a
necessidade de ficar concatenando pedaos de string para compor a string final.

Disponibilidade do recurso
Este recurso est disponvel apenas no produto Microsiga Protheus 8.11.

A utilizao do Embedded SQL divide-se em:

Compilao de cdigo fonte.


Execuo de cdigo fonte.
Para compilar um cdigo fonte com o cdigo escrito no formato Embedded, deve-se utilizar o
produto Microsiga Protheus, com build igual ou superior a 7.00.050721P, em um ambiente
com repositrio para TOPConnect (RPODB=TOP). A utilizao deste recurso, tambm depende
da atualizao da LIB 8.11, superior a LIB 20050902 - 811.

Exemplo bsico - Cdigo fonte atual

Exemplo bsico - Fonte atual

cQuery : 'SELECT SE2.E2_PREFIXO,SE2.E2_NUM '


cQuery += 'FROM '+RetSqlTable('SE2')+' SE2,'+RetSqlTable('QEK')+' QEK '

cQuery += 'WHERE SE2.E2_FILIAL= '+xfilial('SE2')+' AND '


cQuery += 'SE2.E2_PREFIXO<> ''+cPrefixo+'' AND '
cQuery += 'SE2.D_E_L_E_T_ = ' ' '
cQuery += 'ORDER BY '+RetSqlOrder('SE2')

dbUseArea(.T.,'TOPCONN',TcGenQry(,,cQuery),'E2TEMP',.T.,.T.)

TCSetField('E2TEMP','E2_EMISSAO','D',8,0)

Exemplo bsico - Utilizando Embedded SQL

BeginSql alias 'E2TEMP'


column E2_EMISSAO as Date
%noparser%
SELECT SE2.E2_PREFIXO,SE2.E2_NUM
FROM %table:SE2% SE2,%table:QEK% QEK
WHERE SE2.E2_FILIAL= %xfilial:SE2% AND
SE2.E2_PREFIXO<> %exp:cPrefixo% AND
SE2.%notDel%
ORDER BY %Order:SE2%
EndSql

Caractersticas operacionais - Sintaxe


O bloco de cdigo onde ser escrito o comando SELECT, deve sempre ser iniciado com
BeginSQL Alias e finalizado com EndSQL.

Partes do cdigo fonte que devem ser substitudos aparecem entre os sinais de %
(porcentagem). Essas expresses possuem tratamentos especiais em momento de execuo.
Qualquer instruo colocada entre BeginSQL ... EndSQL, que no seja uma expresso %...%,
ser inserida na query que ser enviada para o banco de dados, de forma literal.
Variveis, expresses e funes aparecem iniciando com %exp:%.
Em column deve-se especificar campos da query que so do tipo de dado data, lgico ou
numrico (DATE, LOGIC, NUMBER). Esta linha trocada por chamadas funo TCSetField().
%noparser% indica que a query no deve passar pela funo ChangeQuery() antes de ser
enviada ao banco de dados. Caso no especificado, o padro a string da query ser passada
automaticamente pela funo ChangeQuery().
%table:% substituda por RetSqlName().
%notDel% substituda por D_E_L_E_T_=' '.
%Order:% substituda por SqlOrder (->(IndexKey())).

H 3 opes para o %Order:

1 Opo:

%Order: % traduzido para SqlOrder(->(IndexKey()))

2 Opo:

%Order: , % traduzido para SqlOrder(->(IndexKey()))

3 Opo:

%Order: , % traduzido para SqlOrder(->(DBNickIndexKey()))

Limitao
No permitido incluir funes no meio do cdigo embedded. Se precisar, o valor deve ser
guardado em uma varivel antes do incio do BeginSQL.

Exemplo:

tam_cp := GetE2ValorSize()
BeginSql alias 'E2TEMP'
column E2_EMISSAO as Date, E2_VALOR as Numeric(tam_cp,2)
...
EndSql

Erros de compilao
Caso seja utilizado algum argumento invlido para especificar as colunas ou erros de sintaxe
nas expresses que sero transformadas para montagem da query, a compilao do cdigo
fonte interrompida com a ocorrncia Syntax Error, informando a linha em que a primeira
ocorrncia foi encontrada.

EndSQL (Error C2001 Syntax error:)


Caso a ocorrncia de compilao aponte diretamente para a linha do cdigo fonte, em que
est escrita a instruo EndSQL, verifique se existe algum espao em branco ou tabulao, a
partir do incio da linha, antes da instruo EndSQL. A verso atual deste ambiente no suporta
esta declarao, exigindo que a instruo EndSQL seja alinhada esquerda do cdigo fonte,
sem espao ou tabulaes.

Erros de execuo
Query Argument Error: Alias [XXX] already in suse.
Caso a instruo BeginSQL especifique um alias que j esteja aberto (em uso), a aplicao
abortada com ocorrncia de erro fatal, informando em XXX o alias utilizado.

Query Argument Error: Invalid Value Type [X]


Caso alguma expresso informada na query, atravs da tag %exp:...%, retorne um valor do tipo
diferente de C (Caracter), D (Data), N (Numrico) ou L (lgico), a aplicao abortada com
ocorrncia de erro, em que o tipo do argumento inesperado apresentando em [X].

Type Mismach on +
Esta ocorrncia, se reproduzida, informar na pilha de chamadas o nmero da linha do cdigo
fonte correspondente instruo EndSQL. Essa ocorrncia ocorre caso alguma funo
intermediria do engine do Embedded SQL, exclundo-se as funes especificadas na query
com a sintaxe %exp:...%, retornar um contedo no caractere que ser acrescentado na query.
Esta ocorrncia mais dificil de localizar, sendo til nestes casos a anlise do arquivo
temporrio gerado pelo Protheus IDE, no momento da compilao.

Help NOFUNCW - Funo __EXECSQL


Caso um cdigo fonte Embedded SQL seja executado em um repositrio que no tenha sido
atualizado ou que no seja um repositrio para o ambiente TOPConnect (RPODB=TOP), a
aplicao exibir essa ocorrncia, indicando que a funo interna de execuo da query no
est presente no ambiente. Verifique se a LIB est atualizada e se o RPO, em uso, pertence a
um ambiente TOPConnnect.

Caracterstica operacionais - Depurao


Dada a montagem da query, no possvel depurar o bloco do cdigo compreendido entre as
intrues BeginSQL e EndSQL, no sendo considerados pontos de parada de depurao
(BreakPoints), caso colocados neste intervalo do cdigo. A colocao de pontos de parada
deve ser realizada antes ou depois desse bloco.

Funo auxiliar - GetLastQuery()


Aps a abertura do cursor, no alias especificado, a funo GetLastQuery() retorna um array,
com 5 elementos, onde esto disponveis as seguintes informaes sobre a query executada.

[1] cAlias - Alias usado para abrir o cursor.


[2] cQuery - Query executada.
[3] aCampos - Array de campos com critrio de converso especificados.
[4] lNoParser - Caso verdadeiro (.T.), no foi utilizada a funo ChangeQuery() na string
original.
[5] nTimeSpend - Tempo, em segundos, utilizado para abertura do cursor.

Exemplo mais completo


AdvPL
BeginSql alias 'E2TEMP'
column E2_EMISSAO as Date, E2_VALOR as Numeric(tam_cp,2)
column QEK_SKLDOC As Logical

%noparser%
SELECT SE2.E2_PREFIXO,SE2.E2_NUM, SE2.E2_FORNECE, SE2.E2_LOJA,SE2.E2_VALOR,
SE2.D_E_L_E_T_ DEL1, QEK.D_E_L_E_T_ DEL2 , QEK.QEK_SKLDOC, SE2.R_E_C_N_O_
SE2RECNO
FROM %table:SE2% SE2,%table:qeK% QEK
WHERE SE2.E2_FILIAL= %xfilial:SE2% AND
qek.%notDel% and
SE2.E2_PREFIXO<> %exp:cPrefixo% AND
SE2.E2_NUM<> %exp:(cAlias)->M0_CODIGO% AND
SE2.E2_NUM<>45

AND

SE2.E2_FORNECE=%exp:Space(Len(SE2->E2_FORNECE))% AND
SE2.E2_EMISSAO<>%exp:MV_PAR06% AND
SE2.E2_LOJA<>%exp:MV_PAR05% AND
SE2.E2_VALOR<>%exp:MV_PAR04% AND
qek.QEK_SKLDOC<>%exp:MV_PAR03% And
SE2.%notDel%
ORDER BY %Order:SE2,1%
EndSql

Cdigo fonte gerado pelo pr-compilador (PPO)


__execSql('E2TEMP',' SELECT SE2.E2_PREFIXO,SE2.E2_NUM, SE2.E2_FORNECE,
SE2.E2_LOJA,SE2.E2_VALOR, SE2.D_E_L_E_T_ DEL1, QEK.D_E_L_E_T_ DEL2 ,
QEK.QEK_SKLDOC, SE2.R_E_C_N_O_ SE2RECNO FROM '+RetSqlName('SE2')+' SE2,
'+RetSqlName('QEK')+' QEK WHERE SE2.E2_FILIAL= '' +xFilial('SE2')+'' AND qek.D_E_L_E_T_= ' '
and SE2.E2_PREFIXO<> '+___SQLGetValue(CPREFIXO)+' AND SE2.E2_NUM<>
'+___SQLGetValue((CALIAS)->M0_CODIGO)+' AND SE2.E2_NUM<>45 AND SE2.E2_FORNECE=
'+___SQLGetValue(SPACE(LEN(SE2->E2_FORNECE)))+' AND SE2.E2_EMISSAO<>
'+___SQLGetValue(MV_PAR06)+' AND SE2.E2_LOJA<> '+___SQLGetValue(MV_PAR05)+' AND
SE2.E2_VALOR<> '+___SQLGetValue(MV_PAR04)+' AND qek.QEK_SKLDOC<>

'+___SQLGetValue(MV_PAR03)+' And SE2.D_E_L_E_T_= ' ' ORDER BY '+ SqlOrder(SE2>(IndexKey(1))),{{'E2_EMISSAO','D',8,0},{'E2_VALOR','N',tam_cp,2},{'QEK_SKLDOC','L',1,0}},.T.)

Você também pode gostar