Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Can anybody explain this behavior of cursoradapter ?
Message
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00777389
Message ID:
00777928
Vues:
15
Thanks Jim for the example. It shows what we can do with cursoradapters WOW.
The dataenvironment in your example seems similar to DE of my form (my cursors additionaly are updateable, have allowsimultaneousfetch=.F. and and must participate in the same transaction after editing data)
However I do not understand what you exactly suggest ?
When I set FetchSize = -1 like Aleksey suggested for all my cursoradapters - my form started to work properly (without using your code) eg. all cursor use the same dataenvironment datasource/handle and are filled in proper way (tested only with small data sets). Does it mean that:
-it only seems that all is OK ?
-or maybe that such method (just set FetchSize = -1 ) is OK but simply your code is smarter and will work better in case of larger data sets ?
-or maybe your code works always regardles how FetchSize is set ?

BTW. In VFP help parameters are ODBChdbc and ODBChstmt are described in exactly the same way. I try to discover why you print ODBChdbc and ODBChstmt values so I changed FetchSize=-1 (comment/uncomment) and allowsimultaneousfetch (.t./.f.) in your code. And found no reason. ODBChdbc is always the same, ODBChstmt have always different values. What I am missing ? Would you be so kind and explain your idea ?


>Here is a way to share the connection handle but not the statement handle when using multiple CursorAdapters in a DataEnvironment. This way you only have a single SQL Server connection. The code as written tests to see if the DE connection is busy, and if so waits a little while to complete BeforeCursorFill. The dots appear while the connection is busy. You can also run it with the FetchSize = -1, which looks faster to me.
>
>Aleksey may want to comment on whether or not this technique is recommended or optimal. My understanding is that you do not want multiple CursorAdapters (or remote views, for that matter) to share a single statement handle. I'm not sure about the connection handle.
>
>
>SQLDisconnect(0)
>clear all
>clear
>deform1 = CREATEOBJECT('deform')
>=deform1.xcODBCde.oXC1.cursorfill()
>=deform1.xcODBCde.oXC2.cursorfill()
>=deform1.xcODBCde.oXC3.cursorfill()
>=deform1.xcODBCde.oXC4.cursorfill()
>=deform1.xcODBCde.oXC5.cursorfill()
>
>
>DEFINE CLASS deform as Form
>	declasslibrary = Sys(16)
>	declass="xcODBCde"
>ENDDEFINE
>
>DEFINE CLASS xcODBCde as DataEnvironment
>   AutoCloseTables = .F.
>   AutoOpenTables = .f.
>   datasourcetype="ODBC"
>   datasource=SQLSTRINGCONNECT(;
>      "Driver=SQL Server;Server=(local);" + ;
>      "DATABASE=Northwind",.T.)
>
>   PROCEDURE Init
>   		?SQLGetProp(this.DataSource,"Shared"),
>   		SQLSetProp(this.DataSource,"Asynchronous",.F.)
>
>      this.AddObject("oXC1","xCursorAdapter")
>      this.oXC1.Alias = "Cust1"
>      this.oXC1.SelectCmd = ;
>      "select * from customers"
>
>       this.AddObject("oXC2","xCursorAdapter")
>      this.oXC2.Alias = "Ord1"
>      this.oXC2.SelectCmd = ;
>      "select * from Orders"
>
>      this.AddObject("oXC3","xCursorAdapter")
>      this.oXC3.Alias = "prod1"
>      this.oXC3.SelectCmd = ;
>      "select * from products"
>
>      this.AddObject("oXC4","xCursorAdapter")
>      this.oXC4.Alias = "orddet1"
>      this.oXC4.SelectCmd = ;
>      "select * from [order details]"
>
>      this.AddObject("oXC5","xCursorAdapter")
>      this.oXC5.Alias = "Ship1"
>      this.oXC5.SelectCmd = ;
>      "select * from shippers"
>   ENDPROC
>ENDDEFINE
>
>
>DEFINE CLASS xcursoradapter as CursorAdapter
>	breakonerror = .t.
>	DataSourceType = 'odbc'
>	usededatasource = .T.
>*	FetchSize=-1
>	allowsimultaneousfetch = .T.
>	procedure init
>		this.DataSource = SQLConnect(this.Parent.datasource)
>		* Using next line instead also shares statement handle
>		* this.DataSource = this.Parent.datasource
>	endproc
>	PROCEDURE beforecursorfill(lUseCursorSchema, lNoDataOnLoad, cSelectCmd)
>	?
>	do while SQLGETPROP(this.parent.datasource, "ConnectBusy")=.t.
>		??'.'
>		doevents force
>	enddo
>	return .t.
>	endproc
>
>	PROCEDURE aftercursorfill(lUseCursorSchema, lnoDataOnLoad, cSelectCmd, lResult)
>	?lUseCursorSchema, lnoDataOnLoad, cSelectCmd, lResult
>	IF !lresult
>		=AError(atest)
>		?atest[2]
>	endif
>	* Get connection info
>	?SQLGetProp(this.DataSource,"ODBChdbc")
>	??SQLGetProp(this.DataSource,"ODBChStmt")
>	endproc
>enddefine
>
>
>>>>Should each cursoradapter object have its private connection handle ?
>>>When several CursorAdapter objects share the same ODBC connection/statement handle, CursorFill for some of them may fail because another CursorAdapter haven't finished fetch. To workaround this problem set FetchSize=-1 for all CursorAdapter objects or use dedicated ODBC connection/statement handle for each of them. I personally prefer the second.
>>
>>Hi Aleksey
>>I set FetchSize=-1 for all CursorAdapter objects and now the form work as I expected. Thanks!
>>I am curious why you prefer second method (dedicated ODBC connections).
>>For me the method has two seriuos disadvantages:
>>- it is not comfortable in case when several cursors participate in the same transaction (you have to bind conections using token)
>>- it seems that form with many cursor will consume more SQLServer resources than it is needed (I wonder if it could cause exceeding MSDE limits).
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform