Newsgroup: it.comp.lang.visual-basic
Titolo: Confrontare due recordset

Ciao a tutti,
dovrei scrivere una routine per confrontare se due recset sono identici.
Avevo in mente di fare una cosa del genere:
1) Contare se il numero di record č uguali (scorrendo con movnext e
contatore)
2) Se si controllare Field/Field del tipo
	RsA.Fields(Nome).Value=	RsB.Fields(Nome).Value
Ora ero quasi tentato di saltare il primo passo.
Preciso che i recset hanno struttura identica.
Grazie
-- 
DBMS Firebird
VB6 + Ado

 Ora ero quasi tentato di saltare il primo passo.
Io il primo passo lo farei, e' praticamente a costo zero e puo'
accelerare di molto il confronto in molti casi.
Ovviamente usa recordset disconnessi, mi raccomando (cosi' nel primo
passo non devi nemmeno scorrere e contare, usi direttamente la
RecordCount)

 VB6 + Ado
Hai pensato ad una Query di ricerca dati non corrispondenti...?
SELECT T1.Field1
FROM T1 LEFT JOIN Field1 ON T1.Field1 = T2.Field2
WHERE T2.Field2  is Null;
Magari sì.... ma te la propongo ugualmente... perchè a mio avviso
potrebbe essere la soluzione migliore, non sapendo l'ambito in cui ti
muovi...!
@Alex

 RecordCount)
Quindi adOpenStatic, adUseClient, 
e poi 
Set rs.activeconnection=nothing
Solo che l'ultima non mi funziona, e dato che non posso fare
Set AdoConn=nothing
perchè la connessione stessa è usata altrove, dovrei fare una nuova
connessione temporanea solo per quello.
Forse, dato che si dovrebbe trattere di record in numero variabile tra 1 e
20, magari con alcuni casi che arrivano a 100, forse posso scorrere
semplicemente.
Oppure ho visto che quest'apertura da sempre il recordcount corretto:
 adOpenKeyset, adLockPessimistic,
Cosa consigli?
Tnx


Andrea [Work] ha scritto:

Sei sicuro di voler fare questa cosa in questo modo...????
Boh...
@Alex

 Cosa consigli?
Non quest'ultima, visto che bloccheresti l'intera tabella a tutti gli
altri utenti :-D

 muovi...!
Errr...sicuramente per la ricerca di differenze tra due campi e' un
ottimo metodo, ma se vuole cercare le differenze tra tutti i
campi...deve lanciarne una per ogni campo, ho l'idea che la latenza di
rete, la necessita' di SQL Server di ricompilare la query ogni volta,
eseguire un join nuovo ad ogni chiamata e sopratutto potrebbe trovarsi
ad effettuare join su campi piuttosto "improbabili" e lenti...

Drizzt ha scritto:

In effetti ho premesso di non aver dato per scontato la cosa, non
avendo capito bene...
Se i campi non sono molti in ogni caso conviene eseguire la Qry 3-4
volte che ciclare i
Field o i Record... avendo un DB come FireBird in mezzo le prestazioni
sono decisamente
migliori in quel modo, poichè lato Cleint viene restituito solo la
differenza e non 2 interi Set di record...!
E' da valutare però... ed è possibile tu abbia ragione.
@Alex

 Set recDati.ActiveConnection = Nothing
Allora senza Use Client da errore.
Con UseClient non darebbere errore (che poi è "Impossibile eseguire con
l'oggetto aperto, quello standard insomma).
Il fatto è che se non ricordo male, la UseClient setta automaticamente
OpenStatic anche se ne metto un'altro (infatti con il debug.print mi
riporta 3 e non 0)
Per ora non da errore, poi vedo un po' come va il seguito :)


 Sei sicuro di voler fare questa cosa in questo modo...????
Allora ho una routine molto incasinata che ho rifatto.
Questa routine fa un'elaborazione e tira fuori #n righi da inserire in una
tabella.
Se sto modificando un documento, questi righi dovrebbero già esserci, per
cui dovrei effettuare delle update, oppure non farei niente se
l'elaborazione è uguale a quel che c'è.
Quindi faccio tutta l'elaborazione su un recset inteso come struttura dati,
al termine faccio
RsElaborazione=fai elaborazione
Rs.Open SELECT * FROM TABELLA WHERE ID=100
Se Rs=RsElaborazione non fare nulla, altrimenti : 
1) recupera gli id utilizzabili di Rs
2) DELETE FROM TABELLA WHERE ID=100
3) Fai insert SQL con RsElaborazione con eventuali IdRecuperati finchè ne
ho :)
In pratica si tratta della movimentazione del magazzino dalle Bolle.
Se non cambio nulla, non farò nulla, se cambio una QTA o un articolo
elimino quel che c'è e reinserisco la roba nuova calcolata sul
RsElaborazione


 E' da valutare però... ed è possibile tu abbia ragione.
Mi sa che preferisco il recordset, anche perchè il secondo record è usato
come disconnesso, cioè non ha alcun connessione al DB.
Diciamo che usato questo al posto di una matrice, per comodità di
confronto.
Quindi fare una tabella temporanea mi resterebbe molto più scomodo.
Tnx


 Per ora non da errore, poi vedo un po' come va il seguito :)
Giusto per curiosita', visto che tanto sei su quel codice e due righe
in piu' non ti ammazzeranno...puoi verificare quali sono le differenze
di prestazioni tra il confronto campo a campo e quello con il
getstring?
Cosi', per curiosita'...

 Cosi', per curiosita'...
Intendi
str1=rs1.getstring...
str2=rs2.getstring
if len(str1)<>len(str2)	
  diversi
else
  if str1<>str2 then
    diversi
  endif
endif
Guarda ora devo fare una mod. urgente ad un altro programma, ma entro
stasera /domani segui il thread.
Tnx


 VB6 + Ado
Ovviamente concordo, ed ovviamente se lo dicevi prima .... "oramai...."
;-)
@Alex

 ;-)
Si scusa, č andato via un collega e mi devo occupare anche del suo sw,
quindi ho circa 4/5 cose da finire per ieri :D
Quindi sono un po' piů distratto del solito ^_^


 getstring?
Ho pensato anch'io alla GetString, ma mi fa un po' paura per via ad es. di 
tutti i problemi legati ai valori a virgola mobile, che una volta hanno una 
notazione, la volta dopo un'altra...
Ciao 

 volta hanno una notazione, la volta dopo un'altra...
IMHO è il metodo migliore.
Del resto, se deve confrontare due recordset, in un dato momento, avranno 
entrambi le stesse impostazioni.
Ciao
-- 
Gianluca Cannalire
Microsoft MVP/MCP - Visual Basic
http://www.visual-basic.it
http://community.visual-basic.it/gianluca
 

 entrambi le stesse impostazioni.
Allora ho fatto delle prove con 50.000 itereazioni:
1)
      For j = 0 To 50000
        Rs1.MoveFirst: Rs2.MoveFirst
        s1 = Rs1.GetString(adClipString, 1, vbTab, vbNewLine, "")
        s2 = Rs2.GetString(adClipString, 1, vbTab, vbNewLine, "")
        If Len(s1) <> Len(s2) Then
          CompareRecordSet = False
        Else
          If s1 <> s2 Then
            CompareRecordSet = False
          End If
        End If
      Next j
2)
    For j = 0 To 50000
      Rs1.MoveFirst: Rs2.MoveFirst
      For i = 0 To Rs1.Fields.Count - 1
        sFieldName = UCase$(Rs1.Fields(i).Name)
        If Rs1.Fields(sFieldName).Value <> Rs2.Fields(sFieldName).Value hen
           CompareRecordSet = False
           Exit For
        End If
      Next i
    Next j
Ho fatto per un singolo record, per avere un valore uguale entrambe le
volte, dato che la gestring fa anche la movenext, inoltre la 2) è da
aggiustare per paragonare Null<>#valore# che ovviamente da false.
1) - 29 secondi
2) - 27 secondi
1) senza usare la len - 28 sec
Purtroppo il confronto è uguale, nel primo caso c'è una MoveNext implicita
credo. Per ora non posso fare test più precisi.
Io direi che sono equivalenti, tenderei a preferire la 2) perchè mi da
maggior flessibiiltà, esempio un campo (idtabella) non lo devo confrontare.
Con un
        Select Case sFieldName
          Case "IDTABELLA"    'campi da non confrontare
          Case Else
Faccio come preferisco
