有一个与此相关的问题:
将参数传递给SQLCommand的最佳方法是什么?
但是我想知道区别是什么,以及不同方式是否存在任何问题。
我通常使用这样的结构:
using (SqlConnection conn = new SqlConnection(connectionString)) using (SqlCommand cmd = new SqlCommand(SQL, conn)) { cmd.CommandType = CommandType.Text; cmd.CommandTimeout = Settings.Default.reportTimeout; cmd.Parameters.Add("type", SqlDbType.VarChar, 4).Value = type; cmd.Connection.Open(); using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) { adapter.Fill(ds); } //use data }
现在有几种添加cmd参数的方法,我想知道哪种方法最好:
cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob"; cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob"; cmd.Parameters.Add("@Name").Value = "Bob"; cmd.Parameters.AddWithValue("@Name", "Bob");
我认为在传递varchars时具有字段长度是不可取的,因为这是一个不可思议的值,以后可能会在数据库中更改它。它是否正确?它是否会导致以这种方式传递varchar的任何问题(性能或其他问题),我认为它默认为varchar(max)或等效的数据库。我很高兴这会成功。
如果我使用上面列出的第三个或第四个选项,而我根本不提供类型,则与我更相关的部分是SqlDbType枚举的丢失。在某些情况下这行不通吗?我可以想象varchar被错误地转换为char的问题,反之亦然,或者十进制转换为金钱的问题…。
就数据库而言,我要说的字段类型比长度更改的可能性要小得多,是否值得保留?
以我的经验,我将确保自己执行以下操作:
cmd.Parameters.Add("@Name").Value = "Bob";
cmd.Parameters.AddWithValue(“@Name”, “Bob”);
让ADO.NET通过传递的值来猜测参数的类型是棘手的,并且如果由于某种原因将其关闭,则这些跟踪和查找的确是棘手的错误!想象一下,当您传入DBNull.Value-ADO.NET应该选择哪种数据类型时会发生什么?
DBNull.Value
明确一点-说出您想要的类型!
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";
如果不提供长度,则ADO.NET可能默认为某个任意值,或者作为值传递的字符串的长度,或者其他方式- 您永远不确定。而且,如果您的长度与存储过程的实际期望不符,您可能会看到转换和其他不愉快的惊喜。因此,如果您定义一个字符串,也要定义其长度!
因此,在您的情况下,唯一对我有效的方法是此方法:
cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";
因为它a)定义要显式使用的数据类型,并且b)显式定义字符串的长度。