一尘不染

添加SqlCommand参数时应何时使用“ SqlDbType”和“大小”?

c#

有一个与此相关的问题:

将参数传递给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的问题,反之亦然,或者十进制转换为金钱的问题…。

就数据库而言,我要说的字段类型比长度更改的可能性要小得多,是否值得保留?


阅读 203

收藏
2020-05-19

共1个答案

一尘不染

以我的经验,我将确保自己执行以下操作:

  • 确保是您为参数定义了 数据类型 。ADO.NET在猜测方面做得不错,但是在某些情况下,它可能会非常糟糕-因此,我将避免使用此方法:
    cmd.Parameters.Add("@Name").Value = "Bob";
    

    cmd.Parameters.AddWithValue(“@Name”, “Bob”);

让ADO.NET通过传递的值来猜测参数的类型是棘手的,并且如果由于某种原因将其关闭,则这些跟踪和查找的确是棘手的错误!想象一下,当您传入DBNull.Value-ADO.NET应该选择哪种数据类型时会发生什么?

明确一点-说出您想要的类型!

  • 如果您使用的是字符串参数,请确保 明确定义长度 -因此,我也将避免使用此方法:
    cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";
    

如果不提供长度,则ADO.NET可能默认为某个任意值,或者作为值传递的字符串的长度,或者其他方式-
您永远不确定。而且,如果您的长度与存储过程的实际期望不符,您可能会看到转换和其他不愉快的惊喜。因此,如果您定义一个字符串,也要定义其长度!

因此,在您的情况下,唯一对我有效的方法是此方法:

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

因为它a)定义要显式使用的数据类型,并且b)显式定义字符串的长度。

2020-05-19