积极答复者
用微软提供的JDBC执行存储过程时为什么会执行sp_sproc_columns

问题
-
当数据库的连接数到在350以上时,CPU就会很高,根据监控发现在执行用户存储过程时会首先执行 "exec sp_sproc_columns @procedure_owner=dbo, @procedure_name=proc_name, @ODBCVer=3" 并且很消耗时间,这是怎么回事
CallableStatement cstmt = con.prepareCall("{call proc_name(?, ?)}");
cstmt.setInt(para1name, 5);
cstmt.registerOutParameter(para2name, java.sql.Types.INTEGER);
cstmt.execute();执行到 "CallableStatement cstmt = con.prepareCall("{call proc_name(?, ?)}"); " 数据库就会执行 "exec sp_sproc_columns @procedure_owner=dbo, @procedure_name=proc_name, @ODBCVer=3"这条语句,返回的是存储过程参数的信息.可是我已经通过cstmt.setInt(para1name, 5); 设置了参数名和值,为什么还要从数据库调用参数信息呢?
我是天生我怕谁?
答案
-
一个原因是CallableStatement需要支持named parameter,在设定参数或者取结果时候,可能需要做name -- index转换。作为对比,PreparedStatement就只能用index设定参数。
另外一个原因是,sp可以有很多参数并有默认值;这样对于程序里面没有指定的参数,它可以自动使用默认值。
- 已标记为答案 Hong-Gang Chen - MSFTModerator 2010年4月2日 2:42
全部回复
-
一个原因是CallableStatement需要支持named parameter,在设定参数或者取结果时候,可能需要做name -- index转换。作为对比,PreparedStatement就只能用index设定参数。
另外一个原因是,sp可以有很多参数并有默认值;这样对于程序里面没有指定的参数,它可以自动使用默认值。
- 已标记为答案 Hong-Gang Chen - MSFTModerator 2010年4月2日 2:42
-
看起来应该是在执行cstmt.setInt(para1name,5)这个语句之后,你才会在服务端看到exec sp_sproc_columns。不知道你用的jdbc driver是什么版本?
作为性能优化,你可以考虑使用位置参数来避免这个开销。
cstmt.setInt (1, 5);
cstmt.registerOutParameter (2, java.sql.Types.INTEGER);
用的是: Microsoft SQL Server JDBC Driver 2.0是在 执行CallableStatement cstmt = con.prepareCall("{call proc_name(?, ?)}"); 之后就有exec sp_sproc_columns了.不是在cstmt.setInt(para1name,5)这个语句之后
我是天生我怕谁?