设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 5493|回复: 1
打印 上一主题 下一主题

[分享]sp_prepare你用过吗?

[复制链接]
跳转到指定楼层
1#
发表于 2005-3-11 23:44:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


最近研究ADO的数据构形技术的时候,跟踪SQL Server发现有如下的SQL代码被执行

SET NO_BROWSETABLE OFF  -- 这个未公开的设置,不知道是什么作用

SET FMTONLY ON select bill_id from  tbl_wh_bill_detail SET FMTONLY OFF

SET NO_BROWSETABLE ON

declare @P1 int

set @P1=22

-- 我要说的就是这个 sp_prepare ,用来预编译SQL语句

exec sp_prepare @P1 output, [url=mailto:N'@P1]N'@P1[/url] uniqueidentifier', N'SELECT * FROM tbl_wh_bill_detail where bill_id = @P1', 1

select @P1

SET NO_BROWSETABLE OFF

SELECT * FROM tbl_wh_bill_head where warehouse = '2002'

SET NO_BROWSETABLE ON

-- 这是我第一次见到 sp_execute 的这种用法,用她来执行预编译SQL语句,比反复调用sp_executesql效率高多了

exec sp_execute 22, '9E44402B-12CF-4AB4-B1A7-00AB21608CDB'

exec sp_execute 22, '44811ABA-5B1E-4CE2-8E67-0744FCEDB072'

exec sp_execute 22, 'BFBAF066-4A28-42E0-9A90-08912DF18E13'

exec sp_execute 22, '16572595-B555-4D8E-96DF-0A48350820A6'

exec sp_execute 22, 'FADD71DA-9381-4207-8266-0D0F0FFECCC0'

/*

--如果用sp_executesql,每一次调用都必须重新编译, 形如:

exec sp_executesql N'SELECT * FROM tbl_wh_bill_detail where bill_id = @P1'

  ,N'@P1 uniqueidentifier'

  ,'9E44402B-12CF-4AB4-B1A7-00AB21608CDB'

*/

以下是ADO的数据构形技术相关的VBA代码:

Private Sub Command25_Click()

    Dim rst As New ADODB.Recordset

    Dim rs As New ADODB.Recordset

    '这种用法是非参数话的构形,效率比以下这种方式低

    'rst.Open "SHAPE {SELECT * FROM tbl_wh_bill_head where warehouse = '2002'} " _

    '       & " APPEND ({SELECT * FROM tbl_wh_bill_detail} AS BillDetail " _

    '       & " RELATE bill_id  TO PARAMETER 0)" _

    '       , CurrentProject.Connection



    '这里用参数话的构形,

    rst.Open "SHAPE {SELECT * FROM tbl_wh_bill_head where warehouse = '2002'} " _

           & " APPEND ({SELECT * FROM tbl_wh_bill_detail where bill_id = ?} AS BillDetail " _

           & " RELATE bill_id  TO PARAMETER 0)" _

           , CurrentProject.Connection

    Set rs = rst("billdetail").Value

   

    Do Until rst.EOF

        Debug.Print rs("bill_id"), rst("bill_code")

        Do Until rs.EOF

            Debug.Print rs("bill_id"), rs("item_name")

        rs.MoveNext

        Loop

        

        rst.MoveNext 'rst 移动记录指针的时候, rs是只是相应的记录, 如果是用参数话的构形,每次只从服务器返回相应的记录,而不是一次性返回所有

    Loop

   

    rs.Close

    rst.Close

    Set rst = Nothing

    Set rs = Nothing

End Sub

为了说明问题,再转贴一篇

来自:t1122, 时间:2002-1-21 22:13:00, ID:875327



以下是李维的书上的测试:

是测试UnPrepared的TADOQuery组件、Prepared的TADOQuery组件以

及TADOStoredProc组件执行新增数据的范例应用程序的执行画面。由于这个范例

应用程序使用了相同的方式新增大量的数据,因此我们可以通过它来测试

UnPrepared的TADOQuery组件、Prepared的TADOQuery组件以及TADOStoredProc

组件相对的执行效率。

执行这个范例应用程序时,也激活了MSSQLProfiler来观察这三个不同的组

件在同样新增数据时执行的行为是什么?下面的数据是UnPrepared的TADOQuery

组件执行新增数据时MS SQL Profiler 观察到的Action Query :

sp_executesql N'insert into ADOTestDatas

(ID, Name, Phone, Address, Salary, EDate)

values

(@P1, @P2, @P3, @P4, @P5, @P6)

', [url=mailto:N'@P1]N'@P1[/url] varchar(10),@P2 varchar(10),@P3 varchar(13),@P4

varchar(50),@P5 float,@P6 datetime', 'K334646237', 'dbuuaiudlo',

'5388648427081',

'icwwoapxxxabukwhbciietruytkpftlgnpqqsclcsprmnhpkxu' ,

99572.479999999996, '20000625 15:27:19:000'

. . .

当应用程序使用UnPrepared的TADOQuery组件新增数据时,对于每一笔新增

的数据,ADO驱动程序都会执行一次上面的SQL命令。从这个观察的结果我们可

以看到,在使用UnPrepared的TADOQuery组件时,MSSQLServer会将每一笔新增

数据的ActionQuery编译成一个暂时的存储过程,再执行它。因此,如果新增了

1000笔数据,那么Action Query 便被编译了1000次。

下面的数据则是当Prepared的TADOQuery组件执行时MS SQL Profiler 观察到

的结果。可以看到,当使用Prepared的TADO Query组件时,MSSQL Server 只会先

编译Action Query 一次成为一个暂时的存储过程:

decla
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅

点击这里给我发消息

2#
发表于 2005-3-25 18:56:00 | 只看该作者
好心得!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-11-26 04:28 , Processed in 0.092996 second(s), 26 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表