Página 1 de 1

Indices Temporários

Enviado: 31 Ago 2015 23:14
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

Indices Temporários

Enviado: 01 Set 2015 08:17
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.

Indices Temporários

Enviado: 01 Set 2015 09:33
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

Indices Temporários

Enviado: 01 Set 2015 09:44
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.

Indices Temporários

Enviado: 01 Set 2015 10:10
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

Indices Temporários

Enviado: 01 Set 2015 10:11
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.

Indices Temporários

Enviado: 01 Set 2015 10:22
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.

Indices Temporários

Enviado: 01 Set 2015 10:25
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

Indices Temporários

Enviado: 01 Set 2015 10:39
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.

Indices Temporários

Enviado: 01 Set 2015 10:56
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.

Indices Temporários

Enviado: 01 Set 2015 14:10
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)

Indices Temporários

Enviado: 01 Set 2015 16:11
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

Indices Temporários

Enviado: 01 Set 2015 17:54
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.

Indices Temporários

Enviado: 02 Set 2015 14:42
por FFreire
Ok... vou tentar isolar e voltamos ao tópico !