Mad*_*Boy 35 c# sql-server performance
当我正在阅读书籍以学习C#(可能是一些Visual Studio 2005
旧书)时,我遇到过SqlCommand.Prepare
每次执行SQL调用时都会使用的建议(无论是'a SELECT
/ UPDATE
或INSERT
SQL SERVER 2005/2008),我都将参数传递给它.但它真的如此吗?
应该每次都这样吗?或者有时候?
它是一个参数传递还是五个或二十个是否重要?
如果有的话应该提供什么?它是否会引人注目(我一直在SqlCommand.Prepare
这里使用并跳过它,从来没有任何问题或明显的差异).
为了问题,这是我使用的常用代码,但这更像是一个普遍的问题.
public static decimal pobierzBenchmarkKolejny(string varPortfelID, DateTime data, decimal varBenchmarkPoprzedni, decimal varStopaOdniesienia) {
const string preparedCommand = @"SELECT [dbo].[ufn_BenchmarkKolejny](@varPortfelID, @data, @varBenchmarkPoprzedni, @varStopaOdniesienia) AS 'Benchmark'";
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) //if (varConnection != null) {
using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
sqlQuery.Prepare();
sqlQuery.Parameters.AddWithValue("@varPortfelID", varPortfelID);
sqlQuery.Parameters.AddWithValue("@varStopaOdniesienia", varStopaOdniesienia);
sqlQuery.Parameters.AddWithValue("@data", data);
sqlQuery.Parameters.AddWithValue("@varBenchmarkPoprzedni", varBenchmarkPoprzedni);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
补充说明:
如果我sqlQuery.Prepare()
像下面的代码一样移动异常被抛出必须明确声明大小,这基本上让我认为sqlQuery.Prepare()
首先使它无用吗?有人可以使用我的例子显示正确的用法吗?
public static decimal pobierzBenchmarkKolejny(string varPortfelID, DateTime data, decimal varBenchmarkPoprzedni, decimal varStopaOdniesienia) {
const string preparedCommand = @"SELECT [dbo].[ufn_BenchmarkKolejny](@varPortfelID, @data, @varBenchmarkPoprzedni, @varStopaOdniesienia) AS 'Benchmark'";
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) //if (varConnection != null) {
using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
sqlQuery.Parameters.AddWithValue("@varPortfelID", varPortfelID);
sqlQuery.Parameters.AddWithValue("@varStopaOdniesienia", varStopaOdniesienia);
sqlQuery.Parameters.AddWithValue("@data", data);
sqlQuery.Parameters.AddWithValue("@varBenchmarkPoprzedni", varBenchmarkPoprzedni);
sqlQuery.Prepare();
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我该怎么办?通过在参数旁边添加.size并执行varPortfel.Lenght(如果它是字符串等)?
Ben*_*man 12
从MSDN文档:
"在调用Prepare之前,请在要准备的语句中指定每个参数的数据类型.对于具有可变长度数据类型的每个参数,必须将Size属性设置为所需的最大大小.如果满足这些条件,则准备返回错误不满足.
如果在调用Prepare之后调用Execute方法,则任何大于Size属性指定的值的参数值都将自动截断为参数的原始指定大小,并且不会返回截断错误.
输出参数(无论是否准备好)必须具有用户指定的数据类型.如果指定可变长度数据类型,则还必须指定最大大小."
此外,"如果CommandType属性设置为TableDirect,则Prepare不执行任何操作.如果CommandType设置为StoredProcedure,则对Prepare的调用应该成功,......"
这通常用于确保最终用户不使用SQL注入技术来添加或删除数据库中不需要的信息.
我查看了它并查看了这篇文章http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.prepare.aspx.您的问题是您需要在运行.Prepare()之前定义参数,然后在运行.Prepare()之后设置参数.现在你正在做两件事.我会尝试这样的事情(注意我没有测试它所以我的语法可能有点偏离).
public static decimal pobierzBenchmarkKolejny(string varPortfelID, DateTime data, decimal varBenchmarkPoprzedni, decimal varStopaOdniesienia) {
const string preparedCommand = @"SELECT [dbo].[ufn_BenchmarkKolejny](@varPortfelID, @data, @varBenchmarkPoprzedni, @varStopaOdniesienia) AS 'Benchmark'";
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) //if (varConnection != null) {
using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
sqlQuery.Parameters.Add("@varPortfelID");
sqlQuery.Parameters.Add("@varStopaOdniesienia");
sqlQuery.Parameters.Add("@data");
sqlQuery.Parameters.Add("@varBenchmarkPoprzedni");
sqlQuery.Prepare();
sqlQuery.ExecuteNonQuery();//This might need to be ExecuteReader()
sqlQuery.Parameters[0].Value = varPortfelID;
sqlQuery.Parameters[1].Value = varStopaOdniesienia;
sqlQuery.Parameters[2].Value = data;
sqlQuery.Parameters[3].Value = varBenchmarkPoprzedni;
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一个好处是,通过这样做,SQL查询计划被编译,缓存和重用.如果对查询的调用量很小,这不是什么大问题,但如果你有很多,那么这样做确实有一些显着的性能优势.
归档时间: |
|
查看次数: |
15991 次 |
最近记录: |