Search  
Friday, May 25, 2012 ..:: Forum ::.. Register  Login
 Forum Minimize
Pentru a putea posta mesaje trebuie să vă înregistraţi.
Notă: Mesajele cu conţinut jignitor sau ilegal (inclusiv cereri de soft piratat) nu sunt acceptate şi vor fi şterse imediat .

Pentru a primi raspunsuri rapide si corecte, scrieti in mesaj ce intentionati sa faceti, ce mesaj de eroare primiti, in ce context si in urma caror actiuni. De asemenea, mentionati versiunea de FoxPro in care lucrati!
Dacă nu specificați versiunea, se consideră VFP 9.0 SP2.

SearchForum Home
  Visual FoxPro  Client/Server  Cursor Adapter...
 Cursor Adapter
 
 2/6/2009 10:01:53 AM
User is offlinearanox
272 posts
4th


Cursor Adapter
 (N/A)
Salut,
Am incercat sa folosesc si eu cursor adapter din VFP9 ...merge destul de bine ....singura problema e ca nu pot sa conditionez selectul...
Adica imi scriu comanda sql catre server da nu imi face filtru ....nu stiu cum pot sa ii pasez variabile catre adaptor pt filtru...
sa zicem ca am un adaptor in care am comanda:
"Select * from tabela"
eu vreau sa fac un filtru...si pun
"Select * from tabela where cimp1=&variabila"
metoda asta nu a dat rezultat....am incercat sa rescriu SelectCmd din cursoradapter...si sa dau requery()...nici asa...
vreo idee ?


Orosz Lorand
 2/6/2009 10:15:41 AM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapter
 (Romania)
 aranox wrote
"Select * from tabela where cimp1=&variabila"
metoda asta nu a dat rezultat....am incercat sa rescriu SelectCmd din cursoradapter...si sa dau requery()...nici asa...
vreo idee ?


SELECT * FROM tabela WHERE camp1=?variabila

Inainte de a apela oricare metoda a CA care executa acest select trebuie sa te asiguri ca variabila exista si este vizibila pentru CA.
Eu prefer forma asta:
SELECT * FROM tabela WHERE camp1=?this.proprietate

Creez proprietatea respectiva in CA si o initializez cu o valoare care nu va returna nimic (ex. 'XXX')
Iar in CA.BeforeCursorFill, CA.BeforeCursorRefresh, etc. (sau, in clasa parinte a CA, o metoda apelata din toate aceste metode, sau bindevent, daca CA e in clasa de baza) pun:

IF VARTYPE
(variabila)=VARTYPE(this.proprietate)
   This.proprietate=variabila
ENDIF

In acest mod, CA este de sine statator, nu este nevoie sa i se transmita variabila inainte de fiecare refresh, update, etc ... si nici nu da eroare daca vreuna din aceste metode este apelata fara ca variabila sa existe.



Daniel Buduru
 2/6/2009 12:51:37 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapter
 (N/A)
ok..ai dreptate.
stiu ca pare stupid....da cum creezi un CA programatic ?
adica, eu am folosit builder din fox pentru a aduga un CA, dar ma gindeam ca se poate face si din cod, astfel pot seta run-time direct denumirea cursorului, etc...


Orosz Lorand
 2/6/2009 12:55:43 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapter
 (N/A)
nu ai cumva un form cu CA ca exemplu ?


Orosz Lorand
 2/6/2009 1:00:33 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapter
 (N/A)
 aranox wrote
ok..ai dreptate.
stiu ca pare stupid....da cum creezi un CA programatic ?
adica, eu am folosit builder din fox pentru a aduga un CA, dar ma gindeam ca se poate face si din cod, astfel pot seta run-time direct denumirea cursorului, etc...



oCA=NewObject('CursorAdapter')
oCA.Alias='cursoralias'
oCA.SelectCmd='Select * from table'
....

E indicat sa-ti creezi o clasa proprie pentru CA, cu metodele si proprietatile de care ai nevoie, si sa derivezi CA din aceasta, poti reduce mult din configurarile necesare in runtime.


Daniel Buduru
 2/6/2009 1:04:13 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapter
 (Romania)
 aranox wrote
nu ai cumva un form cu CA ca exemplu ?


Din pacate, tot ce am este facut cu framework-ul meu, si nu prea am cum sa extrag ceva care sa functioneze stand-alone ... Pe de alta parte, nici upload-ul nu functioneaza ...
Am sa vad ce pot face.
Cu ce backend lucrezi? VFP sau un server SQL?



Daniel Buduru
 2/6/2009 1:08:11 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapter
 (Romania)
Mai bine, da-mi un exemplu de form de-al tau, fara CA, si iti arat cum se lucreaza cu CA. Daca ai lucrat cu views, locale sau remote, CA le poate inlocui in aplicate fara modificari.


Daniel Buduru
 2/6/2009 5:04:03 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
scuze de intirziere, da am avut ceva de rezolvat.
Pai, lucru cu MySQL, si pina acu era facut cu sqlexec(...)
Nu ar fi mare problema cu el ca functioneaza si ma descurc destul de bine cu el.
Recent am preluat o aplicatie scrisa in VFP7 si vreau sa o trec pe 9, eu lucrind cu 9 inainte, sunt obisnuit cu multe functii din 9.
Avind in vedere ca tabelele care trebuie sa le folosesc au marime considerabila...1+ mil rows...nu pot aduce toate deodata, pina acu fiind rezolvat cu paginatie.
Problema aparea cind vroiai sa te pozitionezi cu cursorul pe o anumita inregistrare, mai dadea fail ....rar ..da se intimpla.
Ma gindeam ca cu CA se rezolva multe probleme, in primul rind cantitatea de date pe care o aduce la un fetch, plus pozitionarea nu cred ca ar mai fi problema.

Toate bune pina aici...da eu tre sa refac partea care aduce date ...sa pastrez denumirile, asta ca sa nu ma apuc sa rescriu de la 0 tot.
Deci ce ma gindeam eu este sa creez un CA cu acelasi alias care e folosit si pina acum, si sa pun selectul care este si acum in SelectCmd
Astfel am cred ca cel mai putin de lucru, si va functiona cum trebe.


Orosz Lorand
 2/6/2009 6:47:23 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (Romania)
Solutia pe care o ai in vederea se poate implementa fara probleme. In plus fata de SQLEXEC, CA isi pastreaza cursorul, ca si un view, atunci cand se executa  REQUERY(alias) sau CA.CursorRefresh (la CursorFill cursorul este recreat si capata un nou nume temporar, ca si in cazul sqlexec). Asta face dintr-un cursor creat cu CA candidatul ideal pentru afisarea in grid.
CA mai prezinta unele avantaje fata de sqlexec: daca selectul este parametrizat, ca in exemplul tau din primul post, e suficient sa atribui o alta valoare variabilei parametru si sa faci REQUERY() pe cursorul CA, sau CA.CursorRefresh pentru a obtine un alt set de inregistrari, in acelasi cursor.
In metodele After... (AfterCursorFill, AfterCursorRefresh, etc) poti pune cod care sa modifice un camp, sa execute functii vfp inexistente in limbajul serverului, sa indexeze cursorul, sau sa obtina un cursor derivat din el.
In BeforeCursorUpdate, BeforeCursorInsert, BeforeCursorDelete poti pune cod care sa modifice datele inainte de a fi trimise pe server.
Spre exemplu, in selectcmd ai un camp datetime si doua campuri blank, data si ora, pe care le completezi in AfterCursorFill si AfterCursorRefresh. Apoi, in BeforeCursorUpdate si BeforeCursorInsert recompui campul datetime din data si ora.
In SelectCmd poti pune orice secventa de cod acceptata de catre server, la fel ca si in SQLEXEC, nu numai selectul propriu-zis. Poti seta de ex. prima zi a saptamanii, fara sa trebuiasca sa faci setari globale pe server pentru asta. Poti face un CA sa lucreza ca si o procedura stocata pe server combinata cu o procedura VFP, sa execute mult mai mult decat un simplu select. Si totul se executa la o simpla comanda CA.CursorRefresh sau REQUERY(alias), de oriunde din aplicatie. Este o schimbare de abordare fata de SQLEXEC, care face mai eficienta utilizarea CA in anumite conditii.
De asemenea Insert si Update sunt mult mai simplu de gestionat cu CA decat cu SQLEXEC. E suficient un TABLEUPDATE() pe cursor pentru ca CA sa faca automat Insert, Update, Delete pe server pentru inregistrarie carae au fost inserate, modificat sau sterse din cursor.
E bine sa iti faci o clasa pe care sa o subclasezi in aplicatie. Spre ex, metodele BeforeFillRefresh si AfterFillRefresh, pe care le apelezi  din BeforeCursorFill si BeforeCursorRefresh, respectiv AfterCursorFill si AfterCursorRefresh, astfel incat sa nu scrii in doua locuri acelasi cod.

Atentie la CA Builder, are multe buguri ... Parserul pentru selectcmd e dat peste cap de un join sau de un alias in select ... Lista de campuri actualizabile trebuie ajustata manual dupa fiecare modificare a expresiei din selectcmd ... Se intampla uneori ca un CA sa nu mai functioneze corect dupa o modificare cu builderul, desi codul din SelectCmd e ok. Singura solutie de a-l face sa mearga din nou e reconstruirea clasei de la zero ... N-am avut rabdare sa vad ce anume se strica in fisierul clasei, si nici n-am avut timp sa refac builderul complet, am facut doar cateva ajustari minore prin el.
Precizez ca problema e la builder, nu la CA.






Daniel Buduru
 2/10/2009 12:18:50 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
ok,...totul merge destul de bine pina acum da nu reusesc nici cum sa fac sa se vada in grid.
daca dau brow, am datele.
am pus acelasi alias cu care este creat si la grid.....nimic....gridul ramine gol, (in sensul ca e vid.)
unde gresesc ?
Mai e vreo comanda prin care se ataseaza cursorul la grid, altul decit grid.recordsource=.... ?


Orosz Lorand
 2/10/2009 12:54:06 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (N/A)
Dupa ce cursorul s-a instantiat se comporta ca orice cursor VFP.
E ceva in cod care iti scapa, nu sunt motive sa nu mearga ...
Daca ai deja un form functional, in care ai cursoare create cu SLQEXEC, as zice sa instantiezi cursorul fie in dataenvironment, fie acolo unde ai primul SQLEXEC. Pentru a fi creat cursorul se executa CA.CursorFill, apoi, cata vreme selectcmd nu se modifica, se poate face ca.cursorrefresh (sau requery()). Apoi,  acolo unde executi SQLEXEC cu alta valoare a parametrilor sa il inlocuiesti cu REQUERY().
Sau fa un test cu un form, un ca populat din foxuser.dbf, si un grid.

Daniel Buduru
 2/10/2009 1:19:01 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
am gasit intre timp.
dar am alta problema.
de exemplu am asa:

ca.datasourcetype='ODBC'
ca.DataSource = cn

unde cn e o variabila publica de la sqlconnect
eu foloseam o variabila publica pentru conexiune care o initializam la inceput si apoi il bagam in sqlexec(....)
dar vad ca aici nu merge la fel....
desi in help zice asa:

Positive integer that represents or memory variable that contains a valid Open Database Connectivity (ODBC) connection handle

deci daca variabila cn este publica si initializata si imi functioneaza in sqlexec, de ce nu merge si aici ?




Orosz Lorand
 2/10/2009 1:24:00 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
imi da erroarea:
[Microsoft][ODBC Driver Manager]Invalid cursor state


Orosz Lorand
 2/10/2009 1:30:18 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
lol....am rezolvat
dar acu nush de ce merge f incet.
adica sta cam 3 sec pina apare desi e pus fetchasneeded=.t. si cantitatea e 100 ....

Orosz Lorand
 2/10/2009 1:32:02 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
bah...tot imi revine erroarea cu invalid cursor state

Orosz Lorand
 2/10/2009 1:33:07 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
uite aici e codu...

PUBLIC ca
thisform.grid1.RecordSource=''
ca=NEWOBJECT('CursorAdapter')
ca.datasourcetype='ODBC'
ca.DataSource = cn
CA.Alias='test'
CA.FetchAsNeeded=.T.
CA.SelectCmd='Select * from data_facturi'
ca.cursorattach()

IF ca.cursorfill()=.t.
    thisform.grid1.columncount=-1
    thisform.grid1.RecordSourcetype=1
    thisform.grid1.RecordSource="test"
    thisform.grid1.Refresh
else
    AERROR(errorarray)
    MESSAGEBOX(SUBSTRC(errorarray[3],1),16,"Error")
ENDIF ca.cursorfill()


Orosz Lorand
 2/10/2009 1:52:29 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania)
ok...deci is 2 chesti care is naspa rau.
1. Dureaza foarte mult pina se creaza cursorul, chiar daca e pus cu fetch 100 rows si restu cind trebe...el totusi aduce tot da nu afiseaza decit 100....adica ce rost mai are sa afisezi 100 daca tu si asa l-ai adus in ram ?
Idea e sa limitezi traficu pe retea si pe server, sa nu aduci totu deodata. La tabele de citeva mil de rows ..stau de inebunesc. Ce a ce era rezolvat intr-un fel cu paginatie si nu se compara cele 2 la viteza.
2. De ce trebui sa creez o conexiune noua de fiecare data cind rulez formul ?
De ce nu stie sa foloseasca aceasi conexiune cum o face SQLExec() ?

Am avut mari sperante cu CA ....sper sa gasesc inca o solutie...

Orosz Lorand
 2/10/2009 2:31:34 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (N/A) Modified By Daniel Buduru  on 2/10/2009 3:33:43 PM)
1. CA este un wrapper pentru view. Nu influenteaza in nici un fel durata executiei unui select.
Fetch-ul este asa cum este implementat in driver, fie ODBC, fie ADO. Ce driver folosesti in comexiune?
2. De ce sa creezi o noua conexiune? In datasource se poate pune connection handle obtinut anterior cu sqlconnect sau
sqlstringconnect, se va comporta la fel ca si SQLEXEC.

UPDATE
Scuze, n-am vazut posturile dinainte, m-am uitat numai la ultimul, crezand ca e singurul. Revin.

Daniel Buduru
 2/10/2009 3:18:31 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (N/A)
Nu vad de ce nu merge cu conexiunea existenta. Ce eroare da?
CursorAttach nu e necesar acolo.

In ceea ce priveste CA, dupa cam am spus este un wrapper. Se foloseste tot de SQLEXEC, dar face si setarile necesare pentru cursor si conexiune.
Prima executie (CursorFill) poate fi mai lunga decat la sqlexec, cursorrefresh e mai rapida.
Cu fetch n-am lucrat niciodata, am facut intotdeauna in asa fel incat sa pot lucra cu un set redus de date. Cursoare de selectie filtrate, cu cateva campuri, ca sursa pentru lista din care se selecteaza inregistrarile ce se doresc examinate sau prelucrate. Toate procesarile la nivel de tabela trecute de pe local pe server.
Daca ai pus la punct o metoda de paginare mai rapida, foloseste-o.
Sau restructureaza cumva aplicatia in asa fel incat sa nu aduci tabele intregi pentru a fi examinate. De obicei, utilizatorul are anume criterii de filtrare (interval de date, locatii, patteneri, articole ....). E mai eficient sa construiesti un filtru dupa care sa extragi de fiecare data setul necesar decat sa aduci toata tabela ...



Daniel Buduru
 2/10/2009 3:48:53 PM
User is offlinearanox
272 posts
4th


Re: Cursor Adapters
 (Romania) Modified By aranox  on 2/10/2009 4:49:55 PM)
 aranox wrote
imi da erroarea:
[Microsoft][ODBC Driver Manager]Invalid cursor state


am scris mai sus

PS am scos linia aia si tot asa e.
asta se intimpla daca dau release la form si dau run din nou

Orosz Lorand
 2/10/2009 4:53:25 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (N/A) Modified By Daniel Buduru  on 2/10/2009 6:03:20 PM)
 aranox wrote
 aranox wrote
imi da erroarea:
[Microsoft][ODBC Driver Manager]Invalid cursor state


am scris mai sus

PS am scos linia aia si tot asa e.
asta se intimpla daca dau release la form si dau run din nou

CA.CursorFill nu are legatura cu asta, am zis doar ca nu e necesara comanda.

In ceea ce priveste "Invalid cursor state", e legat de driverul ODBC. O cautare pe Google cu ODBC "invallid cursor state" returneaza vreo 10.000 de rezultate ... Cu diverse servere si sin diverse aplicatii.

Incearca sa pui CA.AllowSimultaneousFetch=.t.
Daca ai declarat conexiunea asincrona, executa SQLCANCEL(cn) la iesirea din form.
Poti obtine un nou handle pe conexiunea cn, daca e creata cu atributul shareable (vezi SQLSTRINGCONNECT), apoi executi:
cn2=SQLCONNECT(cn)
ca.datasource=cn2
iar la iesirea din form pui SQLDISCONNECT(cn2).


Daniel Buduru
 2/10/2009 4:57:37 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (N/A)
Vezi aici mai mult despre data fetching:
http://msdn.microsoft.com/en-us/library/aa975670(VS.71).aspx

Daniel Buduru
 2/10/2009 5:16:09 PM
User is offlineDaniel Buduru
2335 posts
1st




Re: Cursor Adapters
 (N/A)
Am facut un test.
Atata vreme cat nu s-a returnat intregul set de inregistrari, SQLGETPROP(cn,'ConnectionBusy') returneaza .T.
Cata vreme conexiunea e busy, nu se poate deconecta, deci va trebui executat SQLCANCEL(cn).




Daniel Buduru
  Visual FoxPro  Client/Server  Cursor Adapter...

Search  Forum Home         

 Google Ads Minimize

    

Copyright 2002-2010 Profox   Terms Of Use  Privacy Statement