Reaproveitamento da estrutura Dbuserarea com #FWTemporaryTable

Bom dia,

Gostaria de saber se tem como substituir a DbUserArea pela "função" FWTemporaryTable() no trecho abaixo reaproveitando a estrutura já criada na "cQry" já criada sem fazer muitas alterações.

cQry += " ORDER BY E1.E1_FILIAL,E1.E1_MOEDA,E1.E1_CLIENTE, E1.E1_LOJA, A1.A1_NREDUZ, A1.A1_NOME "

TRB := CriaTrab(Nil, .F.)

TCQuery cQry new alias "teste"

dbselectarea("teste")

COPY TO &TRB

dbCloseArea()


DbUseArea(.T., , TRB, "AGP", .F., .F.)

procregua(LastRec()) AGP->(dbGoTop()) if AGP->(EOF()) _lRet := .F. AGP->(DbCloseArea()) endif Ferase("TRB")

1 curtida

Francisco, boa tarde!

As funções CriaTrab e DbUseArea foram descontinuadas. Caso você queira simplesmente dar um select e retornar a em uma tabela temporária, você pode usar a função MPSysOpenQuery(). Caso você queria manipular a tabela temporária efetuando replaces, tem que usar a FwTemporaryTable(). Segue abaixo as documentações:

https://tdn.totvs.com/display/framework/FWTemporaryTable

https://tdn.totvs.com/display/framework/MPSysOpenQuery

Opa… então no caso poderia simplesmente usar a MpSysOpenQuery e dispensar o DbUserArea no trecho passado que ele vai reconhecer os campos manipulados na parte inferior?

Correto, Francisco. O MpSysOpenQuery funciona de forma bem parecida com o DbUseArea. Ele cria a tabela temporária “TMP” e você consegue trabalhar com os dados que tem no retorno. Caso você precise manipular o select, melhor criar uma tabela temporária e trabalhar com ela. Espero ter ajudado.

Boa tarde Francisco,

Você pode e consegue abrir sua query, aproveitar a estrutura da mesma (dbStruct) para a criação da tabela temporária, porém você precisará fazer um while para copiar os dados e removendo assim o COPY TO, embora seja possível, não recomendo essa abordagem, você terá de refatorar o código ainda para remover o CriaTrab, ProcRegua etc.

Como trabalhamos muito com o legado, acabamos acostumando com os comandos ISAM, porém com a tabela temporária, podemos fazer as coisas de forma diferente, pois a mesma está no banco de dados, então não precisamos fazer a cópia de valores no servidor, podemos criar querys que permitem fazer a cópia no próprio banco de dados, exemplo:


INSERT INTO TABELA_TEMPORARIA (CAMPO)
SELECT CAMPO FROM TABELA_ORIGEM

Como você tem uma query, você não precisa mais abrir ela, você pode criar a tabela temporária com a estrutura necessária, e sua query na verdade vira um insert para a tabela temporária, esse processo tem um ótimo ganho de performance!


No artigo abaixo existem alguns exemplos de como trabalhar com a tabela temporária:

https://medium.com/totvsdevelopers/protheus-tabela-tempor%C3%A1ria-b2e955f43be4

Daniel, veja minha resposta neste tópico logo abaixo.

Aproveitando essa thread, tenho um arquivo exemplo baixado do tdn onde a classe FWTemporaryTable possui os metodos :InsertSelect() e tambem :InsertIntoSelect().

Isso foi descontinuado?

Segue as linhas existentes no fonte (que foi retirado do TDN)


oTempTable:InsertIntoSelect( {"DESCR", "CONTR" } , RetSqlName("CT0") , { "CT0_DESC", "CT0_CONTR" } )
oTempTable:InsertSelect( RetSqlName("CT0") , { "CT0_DESC", "CT0_CONTR", "CT0_ALIAS" } )