Jump to content
Fivewin Brasil

Obtendo vários registros por partes em instrução SQL (Resolvido)


Ariston Santos

Recommended Posts

Olá, amigos.

Tenho uma tabela de itens com mais de 1000 registros. Preciso ler toda esta tabela em grupos de 20 registros por vez. Qual o comando select para isso?

Imaginei algo do tipo:

FOR nRec := 1 TO RECCOUT() STEP 20

SELECT * FROM ITENS LIMIT nRec, 20

XBROWSE

NEXT

Claro que o exemplo acima é só para clarear as idéias e demonstrar melhor o que preciso, mas não sei se funciona.

Alguém pode me ajudar?

Link to comment
Share on other sites

Ola Ariston

Você pode usar ADO para isso, muito bom, rápido, simples de usar e o xBrowse esta preparado para fazer as movimentações dos ponteiros da tabela sem você precisar fazer nenhum controle.

Eu também uso a SQLRDD, somente para LOCAL, mais para acesso remoto, melhor mesmo o ADO.

Espero ter ajudado.

Link to comment
Share on other sites

Oi, Kleyber.

A ideia é atualizar minha base de dados local a partir de uma tabela na internet.

O problema é que a tabela contém muitos registros e pegar todos de uma vez demora, além de deixar o array muito tufado de registros.

Por isso, pretendo pegar os registros em grupos de 20 por vez.

Como não tenho nenhum campo com código sequencial, pretendo me basear no RECNO() da rabela.

Já tentei assim do modo abaixo mas não deu certo. Embora leia a tabela tantas vezes forem necessário, sempre retorna todos os itens da tabala.

   // Pegar o total de registros
   nCount := 0
   aArray := {}
   SqlArr := "SELECT COUNT(*) FROM itens_bd"
   aArray := SQLArray(SqlArr)
   IF LEN(aArray) > 0
      nCount := aArray[1,1]
   ENDIF

   if nCount == 0
      return nil
   endif

   // Pegar os itens em grupo de 20 ou menos, de acordo com a quantidade de registros na trabela.
   nStep := IIF(nCount > 20, 20, nCount)
   FOR nStart := 1 TO nCount STEP nStep
      aArray := {}
      SqlArr := "SELECT CODIGO, DESCRI, PRVEN1, PRVEN2, PRVEN3 "+;
                   "FROM itens_bd"+; // Origem dos dados
                   " LIMIT "+ALLTRIM(STR(nStart))+","+ALLTRIM(STR(nStep))
      aArray := SQLArray(SqlArr)
      xBrowse(aArray, "Seleção atual")
   NEXT

Link to comment
Share on other sites

Ola Ariston

Tenho uma rotina que é exatamente o que você esta precisando, veja se te atende.

Static Function GravaRegistrosFiliais( cBanco, cCampo, oProgress, cWhere )
****************************************************************************************************************************
***
***
Local k, n, j
Local cCmd, aRet, aRetFilds, lRet
Local cFieldsEstoq := ""
Local aField := { "ARTABMES","ARLCACAO","ARQTDEST","ARQTDENT","ARUSAIDA","ARMOVMES","ARSALINI","ARCHAMD5","SR_RECNO","SR_DELETED", "ARQTDEPO",'ARTOTFAT' }
Local aFieldEstFilial
Local oSql

	Default cWhere := ""

					aFieldEstFilial := Array_SQL("Show Fields FROM "+cBanco ,,,.F.,.F. )

					For j=1 To Len( aField )
						IF ( n := ASCAN( aFieldEstFilial , { |x,y,z| x[1] = Lower( aField[j] ) } ) ) > 0
							aFieldEstFilial := ATrueDel( aFieldEstFilial, n )
						Endif
					Next
					cFieldsEstoq := ""
					cFieldsEstoqSave := ""
					cFieldsEstoqUpda := ""
					For j=1 TO Len( aFieldEstFilial )
						cFieldsEstoq     += Alltrim( aFieldEstFilial[j,1] )+','
						cFieldsEstoqSave += Alltrim( aFieldEstFilial[j,1] )+' = ?,'
						cFieldsEstoqUpda += PadC( "?", Len( Alltrim( aFieldEstFilial[j,1] ) ) )+","
					Next

					cFieldsEstoq     := Subs( cFieldsEstoq, 1, Len( cFieldsEstoq ) - 1 )
					cFieldsEstoqSave := Subs( cFieldsEstoqSave, 1, Len( cFieldsEstoqSave ) - 1 )
					cFieldsEstoqUpda := Subs( cFieldsEstoqUpda, 1, Len( cFieldsEstoqUpda ) - 1 )

					sr_setactiveconnection( nConectMysql )
					aRet := Array_Sql("Select Count("+cCampo+") FROM "+cBanco+cWhere,,,.f.,.f., .t. )
					If !Empty(aRet)
						nLen := aRet[1]
						x := 0
						oProgress:nTotal := nLen
						oProgress:bSetGet := bSETGET( x )
						FOR x=0 TO nLen STEP 100
							oProgress:Set( x )
							cTim := ElapTime( nTime, Time() )
							oTim:Refresh()

							sr_setactiveconnection( nConectMysql )
							cCmd := "Select "+cFieldsEstoq+" FROM "+cBanco+cWhere+" LIMIT "+;
											AllTrimStr(x)+','+AllTrimStr(100)
							aRet := Array_SQL(cCmd,,,.f.,.F.)

							If !Empty( aRet )
								nLen_2 := Len( aRet )

								sr_setactiveconnection( nLocalCnn )
								Array_SQL("SET SESSION AUTOCOMMIT=0",,,.f.,.f.)

								FOR j=1 TO nLen_2
									cSay := "Transferindo "+cBanco+' => '+AlltrimStr( x+j )+" / "+AlltrimStr( nLen )
									oSay:Refresh()

									cCmd := "Select sr_recno FROM "+cBanco+" WHERE "+cCampo+" = '"+AllTrim( aRet[j,1] )+"'"
									aRet2 := Array_SQL( cCmd  ,"_ITENS",       ,.f.       ,.T.      ,       ,  .T.    )
									IF !Empty( aRet2 )
										cCmd := "UPDATE "+cBanco+" SET "+cFieldsEstoqSave+" WHERE sr_recno = '"+AllTrimStr( aRet2[1,1] )+"'"
										lRet := Array_SQL(cCmd,"_GRAVANDO", aRet[j], .t., .t. )
										If ValType( lRet ) == 'L'
											Exit
										EndIf
									Else
										cCmd := "INSERT INTO "+cBanco+" ("+cFieldsEstoq+") VALUES( "+cFieldsEstoqUpda+" )"
										lRet := Array_SQL(cCmd,"_INSERINDO", aRet[j], .t., .t. )
										If ValType( lRet ) == 'L'
											Exit
										EndIf
									Endif
								Next
								If ValType( lRet ) == 'L'
									Exit
								EndIf
							Endif
						Next
						oProgress:Set( x )
						IF !EH_POSTGRES .AND. cBanco == 'estoque'
							Array_SQL( "UPDATE estoque SET ardesativa_produ = 0 WHERE ardesativa_produ IS NULL",,,.F. )
							Array_SQL( "UPDATE estoque SET arlataca = 0 WHERE arlataca IS NULL",,,.F. )
						EndIf

						Array_SQL("SET AUTOCOMMIT=1",,,.f.,.f.)
						SysRefresh()

					Endif

					If ValType( lRet ) == 'L'
						MsgStop("Provavelmente a tabela >>"+cBanco+"<< não esta atualizada na Filial >>"+cSay+"<<","Atenção...")
					EndIf

Return
Link to comment
Share on other sites

Resolvido:

   // Pegar o total de registros
   nCount := 0
   aArray := {}
   SqlArr := "SELECT COUNT(*) FROM itens_bd"
   aArray := SQLArray(SqlArr)
   IF LEN(aArray) > 0
      nCount := aArray[1,1]
   ENDIF

   if nCount == 0
      return nil
   endif

   // Pegar os itens em grupo de 20 ou menos, de acordo com a quantidade de registros na trabela.
   aVetor := {} // Limpa o Vetor
   nStep := IIF(nCount > 20, 20, nCount)
   FOR nStart := 1 TO nCount STEP nStep
      SqlArr := "SELECT CODIGO, DESCRI, PRVEN1, PRVEN2, PRVEN3"+;
                   " FROM itens_bd"+; // Origem dos dados
                   " LIMIT "+ALLTRIM(STR(nStart))+","+ALLTRIM(STR(nStep)) // Delimitador de registros (inicio,fim)
      TRY
         oSql := SR_GetConnection()
         nErr := oSql:Execute( SqlArr ) // Executar o comando em MySQL
         oSql:iniFields(.f.) // ???
         aReturn := {}
         While ( oSql:Fetch( @aReturn ) == SQL_SUCCESS ) // Processar cada registro e salvar em aReturn
            aLinha := {}
            FOR nCol := 1 TO LEN(aReturn) // Pegar cada coluna de aReturn e salvar no array aLinha
                AADD(aLinha, aReturn[nCol])
            NEXT
            AADD(aVetor, aLinha) // Salvar o array aLinha no vetor aVetor
         End
      CATCH oErr
         ? oErr:Description
      END
   NEXT
   xBrowse(aVetor, "Todos os registros")

Obrigado a todos por mais essa força.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...