防止 ADO 连接 SQL Server 时的隐式连接 Report Date : 2002/9 Prepared by : 郑 昀 Article last modified on 200" name="description" />
Report Date: 2002/9 Prepared by: 郑 昀 Article last modified on 2002-9 The information in this article applies to: ü Microsoft SQL Server 2000,7.0 ü Microsoft ADO 2.5 数据库服务器:Microsoft SQL Server 2000以及7.0; 数据库服务器补丁:Microsoft SQL Server 2000 ServicePack1; ADO名称:Microsoft Data Aclearcase/" target="_blank" >ccess - ActiveX Data Objects 2.5 Type Library ADO版本:2.61.7326.0 cnn.Open "Provider=SQLOLEDB.1; Persist Security Info=False;User ID=sa; Initial Catalog=freemail;Data Source=svr;ConnectionTimeout=10", "", "", -1 Set rs = cnn.Execute(sql) 执行这段代码时,在SQL Server Profiler中看到,每个sql语句执行之前都会有一个Audit Login事件。而Audit Login事件的解释是:“收集自跟踪启动后发生的所有新的连接事件,例如客户端请求连接到运行 Microsoft® SQL Server™ 实例的服务器”。也就是说,用Connection对象连接SQL Server之后,每次执行sql语句时仍然会重新建立一次连接,即使用的是同一个Connection?! 建立连接的事件探查记录(按时间顺序)为: EventClass Text Data TraceStart Audit Login (第一次连接) --.network protocol: LPC set quoted_identifier on set implicit_transactions off set cursor_close_on_commit off set ansi_warnings on set ansi_padding on set ansi_nulls on set concat_null_yields_null on set language 简体中文 set dateformat ymd set datefirst 7 SQL:Stm tStarting Select * from users Audit Login (第2次连接) -- network protocol: LPC set quoted_identifier on set implicit_transactions off…略 SQL:Stm tStarting Select * from users Audit Login (第3次连接) -- network protocol: LPC set quoted_identifier on set implicit_transactions off…略 SQL:Stm tStarting Select * from users Audit Logout Audit Logout Audit Logout TraceStop 而如果每句cnn.Execute后面加上rs.close(),则每个execute之前不会有Audit Login事件,而是连续的3个SQL:StmtStarting事件。 这样频繁建立物理连接,是否会影响性能?照例说应该重用同一个连接才对呀? 这种情况叫做隐式登录。 当set一个ADO.Recordset对象接收ADO.Connection.Execute返回的记录集时,就会出现隐式登录,再次和数据库服务器建立一次物理连接,而且这个连接还没有办法重用,也不能池化。 这个的原因是: Because the SQL Server OLE DB provider doesn't permit more than one set of results to be pending on a connection where the results are being returned by means of a forward-only, read-only (default-resultset) cursor, the provider needs to create an additional SQL Server connection to execute a second command on the connection. The provider will only do this implicitly if the Data Source property DBPROP_MULTIPLECONNECTIONS is set to VARIANT_TRUE. 可以参考微软的KB文档: aspx?scid=kb;EN-GB;q271128&GSSNB=1">http://support.microsoft.com/default.aspx?scid=kb;EN-GB;q271128&GSSNB=1 《PRB: Implicit Connections Created by the SQL Server OLE DB Provider (SQLOLEDB) Are Not Pooled》 Dim cn As New ADODB.Connection rs.CursorType = adOpenStatic rs.ActiveConnection = cn rs.CursorType = adOpenStatic 看来,确实如微软所说的,只有接收默认的记录集时才会发生隐式连接。如果设置ADO.Recordset为其它类型,如静态集,就不会发生这个问题。 当然,默认的记录集的属性forward-only、read-only情况执行速度最快。 Writen by zhengyun@tomosoft.com 本文档所包含的信息代表了在发布之日,ZhengYun 对所讨论问题的当前看法,Zhengyun 不保证所给信息在发布之日以后的准确性。 MILY: 宋体; mso-bidi-font-size: 22.0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">防止ADO连接SQL Server时的隐式连接
问题陈述:
sql = "select * from users"
Set rs2 = cnn.Execute(sql)
Set rs3 = cnn.Execute(sql)
Cause:
【不会重复建立数据库连接的代码片断】:
通过改变ADO.Recordset的属性避免隐式登录
Dim rs As New ADODB.Recordset
Dim rs2 As New ADODB.Recordset
cn.open ..........
rs.Open "select * from orders"
rs2.ActiveConnection = cn
rs2.Open "select * from orders"