Indices Temporários

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
FFreire
Usuário Nível 3
Usuário Nível 3
Mensagens: 113
Registrado em: 19 Mai 2013 16:16
Localização: Andirá-PR / Itaporanga-SP

Indices Temporários

Mensagem por FFreire »

Andei lendo aqui sobre tabelas e índices temporários, fiz alguns testes e vi que realmente vale a pena estudar mais...

Gostaria de saber se a sua utilização é igual a de um arquivo físico, com relação a ter vários índices em um mesmo arquivo...

o normal seria assim:

USE TABELA1 NEW ALIAS TAB1 ONLY
INDEX ON CAMPO1 TAG C1 TO TAB1
INDEX ON CAMPO2 TAG C2 TO TAB1
INDEX ON CAMPO3 TAG C3 TO TAB1
DBSETINDEX(TAB1)

Claro que é um exemplo grosseiro, mas só para tirar uma dúvida, pois tentei fazer dessa forma ai, mas usando os comandos que vi por aqui para o esquema dos temporários e notei que fica apenas o ultimo índice...ou seja, na hora que vou usar o índice é que tenho que gerar o que quero... não posso ter isso antecipadamente...

F.Freire
Harbour 3.2.0+MiniGui Extended 16.02+BCC5 / HWGdebug / SIXCDX / PostgreSQL 9.5 / LetoDB 2.15 / Java8
fabiano@ffsoft.com.br
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
Neste exemplo em questão não tem índice temporário.
índice é que tenho que gerar o que quero... não posso ter isso antecipadamente...
No seu exemplo vc está criando alguns indices usando o RDD do Harbour chamado "DBFCDX"
Para acessar os índices neste caso que vc postou usamos.

Código: Selecionar todos

USE TABELA1 NEW ALIAS TAB1 ONLY
INDEX ON CAMPO1 TAG C1 
INDEX ON CAMPO2 TAG C2 
INDEX ON CAMPO3 TAG C3
 
   tab1->(OrdSetFocus(1)) //ordem da indexação 1
   tab1->(OrdSetFocus(2)) //ordem da indexação 2
   tab1->(OrdSetFocus(3)) //ordem da indexação 3
Com uma pequena modificação não precisa do "to tab1"
Já para usarmos índices temporários que irão deixar de existir quando fecharmos o DBF.

Código: Selecionar todos

   Index on campo4 tag c4 temporary
Ao fechar o DBF ele deixa de existir.
ou.

Código: Selecionar todos

   Index on campo4 tag c5 temporary additive
   tab1->(ordDestroy("c5"))  //apagar ordem/indice sem fechar o DBF!
Ou ainda criar TUDO direto na memória RAM.

Código: Selecionar todos


DbStrut := {{ "cliente"   ,"c",60,0},;
            { "vencimento","d",08,0},;
            { "documento" ,"c",20,0},;
            { "valor"     ,"n",14,4},;
            { "emissao"   ,"d",08,0}}

DbCreate("mem:"+"TESTE",DbStrut,'DBFCDX',.T.,"pa")
INDEX ON CLIENTE TAG C1 
CLOSE 
dbDrop("mem:"+"TESTE",,"DBFCDX") //APAGAR DBF E CDX DE UMA VEZ DA MEMÓRIA OU DO HD! (novo Comando)

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
FFreire
Usuário Nível 3
Usuário Nível 3
Mensagens: 113
Registrado em: 19 Mai 2013 16:16
Localização: Andirá-PR / Itaporanga-SP

Indices Temporários

Mensagem por FFreire »

O exemplo que coloquei acima é o usual... o que normalmente todos fazem... a minha dúvida é com relação aos índices em memória... se funcionam da mesma forma... pois estou utilizando os comando para criar os temporários e esta permanecendo apenas um único índice... segue a forma que estou fazendo...

Código: Selecionar todos

      IF !CriaStr( SUBSTR( (_ADbf)->CodStr, 1, 4 ), _Nome, _AArqs[7], _AArqs[8], _AArqs[9], .T., _Caminho, .T., _Alias )
         MsgMenu('Erro na criação do Arquivo '+ _Nome,{'&OK'},,"IM__ERRO",'Erro...',,,'32 ERR CAN',,,_branco_)
         _ret := FALSE
         EXIT
      END
		nIndIni := 0
      IF (_ANtx)->( DBSEEK( (_ADbf)->Codigo ) )
         WHILE !(_ANtx)->( EOF() ) .AND. (_ADbf)->Codigo == (_ANtx)->CodDbf
            _NomeInd := ALLTRIM( (_ANtx)->Nome ) 
            _Tag     := ALLTRIM( (_ANtx)->Tag )
            _Chave   := ALLTRIM( (_ANtx)->Chave )
            IF !NETERR() // tenta travar o arquivo para criacao do indices
               _NomeIndFim := 'MEM:'+_NomeInd
					IF nIndIni = 0
						INDEX ON &(_Chave) TAG &(_NomeIndFim) TEMPORARY
						nIndIni = 1
					ELSE
						INDEX ON &(_Chave) TAG &(_NomeIndFim) TEMPORARY ADDITIVE
					END
               IF REGLOCK( (_ANtx) )
                  (_ANtx)->Normal     := 'S'
                  (_ANtx)->( DBCOMMIT() )
                  (_ANtx)->( DBUNLOCK() )
               END
            END
            (_ANtx)->( DBSKIP() )
         END
		END
		(_Alias)->(DBCLOSEAREA())
		
		_Nome    := 'MEM:'+_Nome		
		NETUSE( _Nome, _Alias, ONLY )
		IF (_ANtx)->( DBSEEK( (_ADbf)->Codigo ) )
			_NomeInd := 'MEM:'+ALLTRIM( (_ANtx)->Nome )
		   DBSETINDEX( _NomeInd )
		END

*****************************
* Funcao.....: CriaStr()
* Finalidade.: Cria o arquivo com base na estrutura

FUNCTION CriaStr( _CodCria, _ArqCria, __Str, __StrI, __AStr, __Recria, __Caminho, __arqtemp, __alias )

// _CodCria  --  Codigo para pesquisa no arq. de Estrutura
// _ArqCria  --  Nome do arquivo a ser criado
// __Str     --  Arquivo de Estruturas dos arquivos
// __StrI    --  Arquivo de Indices da estruturas
// __AStr    --  Alias da Estrutura
// __Recria  --  Se cria o arquivo mesmo que existir
// __Caminho --  Onde sera criado o arquivo

LOCAL _StrDef, aChou, xOpErro
LOCAL _AbreS := .F., __CaminhoLeto

_StrDef   := {}
__Recria  := IIF( __Recria = NIL, .F., __Recria )
__arqtemp := IIF( __arqtemp = NIL,.F., __arqtemp )	

IF EMPTY( SELECT( __AStr ) )
   // Tenta abrir arquivo de (estruturas) em modo compartilhado
   IF NETUSE( __Str, (__AStr), SHARE )
      DBSETINDEX( __StrI )
   ELSE
      MsgMenu('Arq.' + __Str + ' não pode ser aberto !!! Verifique os terminais !!!',{'&OK'},,"IM__ERRO",'Erro...',,,'32 ERR CAN',,,_branco_)
      RETURN( FALSE )
   END
   _AbreS := .T.
END

(__AStr)->( DBSEEK(_CodCria) )
WHILE (__AStr)->Codigo == _CodCria
   AADD( _StrDef, { ALLTRIM((__AStr)->Nome), (__AStr)->Tipo, (__AStr)->Tamanho, (__AStr)->Decimal } )
   (__AStr)->( DBSKIP() )
END

IF EMPTY( _StrDef )
   RETURN( FALSE )
ELSE
	IF !__arqtemp
      xOpErro = 1
      IF FILE(__Caminho+_ArqCria) .AND. !__Recria
         xOpErro :=  MsgMenu('Arq.' + __Caminho +_ArqCria + ' já existe !!! Cria novamente ???',{'&Sim','&Não'},,"IM__PERGUNTA",'Atenção',,,'42 ASK',,,_branco_) = 1
      END
      IF xOpErro = 1
         __CaminhoLeto := zLetoDB + SUBSTR(__Caminho,4,LEN(__Caminho)-3)

         IF EMPTY(zLetoDB)
            DBCREATE(IIF(EMPTY(zLetoDB),__Caminho,__CaminhoLeto) + _ArqCria, _StrDef )
         ELSE
            DBCREATE(IIF(EMPTY(zLetoDB),__Caminho,__CaminhoLeto) + _ArqCria, _StrDef, "LETO" )
         END
         HB_FCOMMIT()
      END
	ELSE
		IF EMPTY(zLetoDB)
			DBCREATE("MEM:"+_ArqCria,_StrDef,"SIXCDX",.T.,__alias)
		ELSE
			DBCREATE("MEM:"+_ArqCria,_StrDef,"LETO",.T.,__alias)
		END
	END		
END

IIF( _AbreS, (__AStr)->( DBCLOSEAREA() ), '' )

RETURN( TRUE )
Esta criando a tabela temporária na memória e esta criando o índice, mas o que quero saber é... tenha uma tabela (de uso temporário) com vários índices, dai quando necessito de um determinado índice uso ORDSETFOCUS(2), por exemplo... ou seja, inicio o sistema, crio a tabela e os índices... dai uso quando preciso... no temporário da para fazer a mesma coisa ou tenho que criar o índice na hora que for usar... pois parece que ele cria apenas 1 índice para 1 tabela... se for assim, tenho apenas que mudar a forma de tratar isso... entro no sistema, gero os arquivos, dai a hora que for usar, populo a tabela e crio o índice que eu quiser...

Só para ficar mais claro....

Se eu fizer assim, da forma que exemplifiquei acima...

temp->(ordsetfocus(1))
alert(temp->(indexkey()) -> irá aparecer o indice 1...ok

temp->(ordsetfocus(2))
alert(temp->(indexkey()) -> irá ficar em branco...

temp->(ordsetfocus(3))
alert(temp->(indexkey()) -> irá ficar em branco...



F.Freire
Harbour 3.2.0+MiniGui Extended 16.02+BCC5 / HWGdebug / SIXCDX / PostgreSQL 9.5 / LetoDB 2.15 / Java8
fabiano@ffsoft.com.br
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
Quando vc trabalha com índices "CDX" é preciso informar antes. Está fazendo isso ?

Código: Selecionar todos

REQUEST DBFCDX, DBFFPT, DBFDBT, LETO
Function MAIN
   RDDSetDefault("DBFCDX") 
   RDDSetDefault("LETO") //ou no CASO do LETO
Como está seu arquivo lá no LETODB.INI ? para NTX ou CDX ?
Pedaço aqui do letodb.ini

Código: Selecionar todos

[MAIN]
Port = 2812              
Logfile = "letodb.log"   
DEFAULT_DRIVER = CDX     
...
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
FFreire
Usuário Nível 3
Usuário Nível 3
Mensagens: 113
Registrado em: 19 Mai 2013 16:16
Localização: Andirá-PR / Itaporanga-SP

Indices Temporários

Mensagem por FFreire »

O Amigão... esquece isso... isso ta tudo funcionando... o meu problema não é esse... o problema é gerar índices temporários... só gostaria de saber se funciona da mesma forma que o normal... da forma tradicional ta tudo certo... seja com leto ou com sixcdx... o que preciso saber é... se com os índices temporários, posso gerar mais de 1 por tabela... se sim... o que será que estou fazendo de errado, pois esta prevalecendo apenas o ultimo índice gerado... APENAS QUANDO USO O ESQUEMA DO TEMPORÁRIO OU EM MEMÓRIA...

F.Freire
Harbour 3.2.0+MiniGui Extended 16.02+BCC5 / HWGdebug / SIXCDX / PostgreSQL 9.5 / LetoDB 2.15 / Java8
fabiano@ffsoft.com.br
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
Esse código aqui, não é assim que eu uso.

Código: Selecionar todos

 DBCREATE("MEM:"+_ArqCria,_StrDef,"LETO",.T.,__alias)
O arquivo é criado no PC local na RAM da estação, não é criado pelo LETO na memória do servidor.

Código: Selecionar todos

 DBCREATE("MEM:"+_ArqCria,_StrDef,"DBFCDX",.T.,__alias)
 INDEX ON xyz TAG TAG1
Nisso você pode criar as TAG's (indices)
Não esquecer de setar o "Set AutOpen On" Abrir automaticamente os índices, sem precisar do "SET INDEX TO ARQUIVO.CDX"

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
o problema é gerar índices temporários...
Ficou difícil de entender aqui, por causa do contexto, exemplo que você usou.
Temporário de uma forma geral, pode ser qualquer índice com o flag temporary ou sem, com NTX ou CDX.

Se é só sobre o MEM: Criado na memória RAM ou se é para usar da forma tradicional do clipper.

Para usar a função OrdSetfocus() é preciso setar antes para múltiplos índices e usar a cláusula TAG quando criar os índices.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
FFreire
Usuário Nível 3
Usuário Nível 3
Mensagens: 113
Registrado em: 19 Mai 2013 16:16
Localização: Andirá-PR / Itaporanga-SP

Indices Temporários

Mensagem por FFreire »

Ok... o que esta me dizendo é que se estiver usando LETO e for usar temporários...não preciso setar o LETO, pois irá criar a tabela na memória do servidor...ok... mas e sobre os indices... posso usar mais de um por arquivo... pois estou tentando aqui e não funciona... prevalece apenas o ultimo da lista...

Veja no código postado que tem o TAG... mas prevalece apenas o ultimo índices...
F.Freire
Harbour 3.2.0+MiniGui Extended 16.02+BCC5 / HWGdebug / SIXCDX / PostgreSQL 9.5 / LetoDB 2.15 / Java8
fabiano@ffsoft.com.br
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
Vê se é isso...

Código: Selecionar todos

REQUEST DBFCDX
Function Main
local	DbStrut := {{ "cliente"   ,"c",60,0},;
	            { "vencimento","d",08,0},;
	            { "documento" ,"c",20,0},;
	            { "valor"     ,"n",14,4},;
	            { "emissao"   ,"d",08,0}}

RDDSetDefault("DBFCDX")
SETMODE(25,80)
DbCreate("mem:"+"TESTE",DbStrut,'DBFCDX',.T.,"pa")
INDEX ON CLIENTE TAG TAG1
INDEX ON DTOS(VENCIMENTO) TAG TAG2
INDEX ON DOCUMENTO TAG TAG3
pa->(ordsetfocus(1))
alert(pa->(indexkey()))
pa->(ordsetfocus(2))
alert(pa->(indexkey())) 
pa->(ordsetfocus(3))
alert(pa->(indexkey()))
Espero que ajude.
Compile e veja o resultado. O tal "self container example" que o povo(desenvolvedores) tanto pede.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
não preciso setar o LETO, pois irá criar a tabela na memória do servidor...ok... mas e sobre os indices... posso usar mais de um por arquivo...
Acredito que não funciona. O letodb não contempla essa situação. Por isso está criando só um índice. Não faz sentido para o programador que criou o LETODB... Além do mais essa nova função MEM: apareceu depois que o letodb já tinha sido criado.
mas e sobre os indices... posso usar mais de um por arquivo...
Como demonstrado no exemplo que postei, pode sim.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Indices Temporários

Mensagem por janio »

No esquema...

DbCreate("mem:"+"TESTE",DbStrut,'DBFCDX',.T.,"pa")

Eu crio mais de um indice por dbf e FUNCIONA!

Código: Selecionar todos

aCampos := {} 
aAdd( aCampos , { "PEDIDO" , "N" ,  8 , 0 } )  // 100 milhoes de registros
aAdd( aCampos , { "NUMCCF" , "N" ,  6 , 0 } )  // numero do cupom fiscal no ecf
aAdd( aCampos , { "NUMCOO" , "N" ,  6 , 0 } )  // numero COO do ECf quando o cupom foi emitido

dbCreate( "mem:test", aCampos, "DBFCDX" , .T., "memarea" )

INDEX ON NUMCCF TAG CHAVE1
INDEX ON NUMCOO TAG CHAVE2

Select MemArea
DbSetOrder(1)

Select MemArea
DbSetOrder(2)
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
FFreire
Usuário Nível 3
Usuário Nível 3
Mensagens: 113
Registrado em: 19 Mai 2013 16:16
Localização: Andirá-PR / Itaporanga-SP

Indices Temporários

Mensagem por FFreire »

Nobres Colegas...

Consegui fazer funcionar... com vários índices por tabelas... tudo ok...

Mas não sei se é a forma que estou usando ou sabe lá o que... que houve outras situações muito estranhas...

Eu sempre usei tabelas temporárias por terminal, mas tudo fica no servidor, em disco, quando lendo sobre esse esquema de poder usar a memória do terminal, logo pensei, vou tentar para ver como fica e realmente notei uma diferença imensa... o que faço em muitas situações é transferir dados da tabela principal para a temporária...dessa forma...

Código: Selecionar todos

                                             // Adiciona nota
                                             IF !(TCmCab)->( DBSEEK( CmPro->( CHAVECOM ) ) )
                                                (TCmCab)->( DBAPPEND() )
                                                FOR nCnt := 1 TO CmCab->( FCOUNT() )
                                                   (TCmCab)->( FIELDPUT( nCnt, CmCab->( FIELDGET( nCnt ) ) ) )
                                                NEXT															
                                                (TCmCab)->( DBCOMMIT() )
                                             END
                                             // Adiciona produtos
                                             (TCmPro)->( DBAPPEND() )
                                             FOR nCnt := 1 TO CmPro->( FCOUNT() )
                                                (TCmPro)->( FIELDPUT( nCnt, CmPro->( FIELDGET( nCnt ) ) ) )
                                             NEXT
                                             (TCmPro)->( DBCOMMIT() )
Ai filtro o que preciso e gravo na temporário, podendo assim fazer uso livre da temporária... dai ajustei e passei a usar temporária, mas deu uns erros que tal campo não existe em tal tabela... como assim... se a temporária é uma cópia da estrutura da principal... dai volto da forma que era e tudo volta ao normal... então por enquanto dei uma desanimada... alguém ja teve algum problema desse ??

O erro da assim... tal campo não existe... mas o campo é de outra tabela que não tem nada a ver... e dá quando executo o dbcommit()

De repente, poderia ser o TCMPRO que esta apontando para outro arquivo... mas não é... pois se fosse ja daria erro quando uso o filedput(), é muito estranho...

F.Freire
Harbour 3.2.0+MiniGui Extended 16.02+BCC5 / HWGdebug / SIXCDX / PostgreSQL 9.5 / LetoDB 2.15 / Java8
fabiano@ffsoft.com.br
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Indices Temporários

Mensagem por Itamar M. Lins Jr. »

Ola!
F.Freire, você tem que isolar o problema e ver qual é a parte, função que apresenta o erro.
Também observar a versão do seu harbour.
Tenta criar um pequeno programa, mas é pequeno mesmo, que demonstre o problema, para que nós possamos executar em nossas máquinas.
Eu uso esse recurso muito, e não tenho problema.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
FFreire
Usuário Nível 3
Usuário Nível 3
Mensagens: 113
Registrado em: 19 Mai 2013 16:16
Localização: Andirá-PR / Itaporanga-SP

Indices Temporários

Mensagem por FFreire »

Ok... vou tentar isolar e voltamos ao tópico !
Harbour 3.2.0+MiniGui Extended 16.02+BCC5 / HWGdebug / SIXCDX / PostgreSQL 9.5 / LetoDB 2.15 / Java8
fabiano@ffsoft.com.br
Responder