当前位置:  开发笔记 > 编程语言 > 正文

将参数传递给SQLCommand的最佳方法是什么?

如何解决《将参数传递给SQLCommand的最佳方法是什么?》经验,为你挑选了3个好方法。

将参数传递给SQLCommand的最佳方法是什么?你可以做:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";

要么

cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";

要么

cmd.Parameters.Add("@Name").Value = "Bob";

看起来第一个可能在某种程度上"更好",无论是性能方面还是错误检查方式.但我想更清楚地知道.



1> Peter Wone..:

那里发生了什么?

您引用了几个重载的参数列表Add.这些是直接对应于SqlParameter类的构造函数重载的便捷方法.它们本质上构造参数对象,使用任何构造函数与您调用的方便方法具有相同的签名,然后调用SqlParameterCollection.Add(SqlParameter)如下:

SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);

AddWithValue是类似的,但进一步方便,也设置值.然而,它实际上是为解决框架缺陷而引入的.引用MSDN,

它的重载Add需要一个字符串,并且一个对象被弃用,因为SqlParameterCollection.Add重载可能存在歧义 ,它带有a StringSqlDbType 枚举值,其中传递带字符串的整数可以被解释为参数值或相应的 SqlDbType值.使用AddWithValue 时,你想要通过指定名称和值添加一个参数.

类的构造函数重载SqlParameter仅仅是设置实例属性的便利.它们缩短了代码,对性能产生了微不足道的影响:构造函数可以绕过setter方法并直接在私有成员上运行.如果有差异则不会太多.

我该怎么办?

请注意以下内容(来自MSDN)

对于双向和输出参数以及返回值,必须设置值Size.输入参数不需要这样做,如果没有显式设置,则在执行参数化语句时,从指定参数的实际大小推断出该值.

默认类型是输入.但是,如果您允许像这样推断大小并在循环中回收参数对象(您确实说您关注性能),那么大小将由第一个值设置,任何后续更长的值将是裁剪.显然,这仅对诸如字符串的可变长度值有意义.

如果在循环中重复传递相同的逻辑参数,我建议您在循环外创建一个SqlParameter对象并适当调整大小.过大的varchar是无害的,所以如果它是一个PITA来获得确切的最大值,只需将它设置得比你预期的那样大.因为您正在循环使用对象而不是为每次迭代创建一个新对象,所以即使您对超大尺寸感到有些兴奋,循环持续时间内的内存消耗也可能会下降.

说实话,除非你处理成千上万的电话,否则这些都不会产生太大的影响.AddWithValue创建一个新对象,回避尺寸问题.它简短,甜美,易于理解.如果你循环数千,请使用我的方法.如果不这样做,请使用AddWithValue以保持代码简单易用.


2008年是很久以前的事了

自从我写这篇文章以来,这个世界已经发生了变化.有新的日期,并且在最近的日期问题让我想到扩大的影响之前,还有一个问题没有出现在我脑海中.

对于那些不熟悉术语的人来说,扩大和缩小是数据类型转换的品质.如果为double分配int,则不会损失精度,因为double是"更宽"的.这样做总是安全的,因此转换是自动的.这就是为什么你可以将一个int分配给一个double但是另一个方法你需要进行一个显式的转换 - double to int是一个缩小的转换,可能会导致精度损失.

这可以应用于字符串:NVARCHAR比VARCHAR宽,因此您可以将VARCHAR分配给NVARCHAR,但是以另一种方式需要转换.比较有效,因为VARCHAR隐式扩展到NVARCHAR,但这会干扰索引的使用!

C#字符串是Unicode,因此AddWithValue将生成NVARCHAR参数.另一方面,VARCHAR列值扩展到NVARCHAR以进行比较.这不会停止查询执行,但会阻止使用索引.这是不好的.

你能为这个做什么?您有两种可能的解决方案.

显式键入参数.这意味着不再有AddWithValue

将所有字符串列类型更改为NVARCHAR.

Ditching VARCHAR可能是最好的主意.这是一个简单的变化,具有可预测的后果,它可以改善您的本地化故事.但是,您可能没有这个选项.

这几天我没有做很多直接的ADO.NET.Linq2Sql现在是我的首选武器,编写此更新的行为让我想知道它是如何处理这个问题的.我突然想要清除我的VARCHAR数据库.



2> Mitch Wheat..:

您也可以使用AddWithValue(),但要注意错误的隐式类型转换的可能性.

cmd.Parameters.AddWithValue("@Name", "Bob");


[使用AddWithValue()可能存在一些问题](http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/)
这是另一种方法,但是问题是最好的方法,而不是肯定的方法。

3> Booji Boy..:

我肯定会说#1。但是,尽管Microsoft在企业库的数据访问应用程序块中做到了这一点,但是最好的选择是,尤其是对于SQL Server:

http://msdn.microsoft.com/en-us/library/dd203144.aspx

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有