为什么SqlParameter总是设置参数为null?

时间:2014-09-05 08:54:56

标签: c# sql sql-server sqlparameter

using (SqlCommand cmd = new SqlCommand())
{
    DataTable dt = new DataTable();
    cmd.CommandText = p;
    cmd.CommandType = CommandType.Text;
    SqlConnection con = new SqlConnection("--");
    cmd.Connection = con;
    cmd.Connection.Open();
    foreach (var parameter in filters)
    {
        var type = parameter.Value.GetType();
        var param = new SqlParameter(parameter.Id, parameter.Value);
        param.Direction = ParameterDirection.Input;
        param.Value = parameter.Value;

        cmd.Parameters.Add(param);
    }
    dt.Load(cmd.ExecuteReader());
    cmd.Connection.Close();
    return dt;
}

这是我的代码。 变量" p"是我的sqlQuery字符串。 变量"过滤器"是我的参数列表。 例如:parameter.Id =" @ offerId" (作为字符串)和parameter.Value = 1230(作为整数) 我的查询也是这样的:" select * from Offers where ID = @offerID and IsActive = @isActive"

当传入cmd.ExecuteReader()时,在IntelliTrace中显示我的查询:

--The data may be truncated and may not represent the query that was run on the server
USE [DB];

GO

--Type and value data was not available for the following variables. Their values have been set to defaults.
DECLARE @offerID AS SQL_VARIANT;
DECLARE @isActive AS SQL_VARIANT;
SET @offerID = NULL;
SET @isActive = NULL;

select  *  from Offers where  ID = @offerID and IsActive = @isActive

我们尝试了很多方法。但是变量总是设置为null。

2 个答案:

答案 0 :(得分:1)

IntelliTrace目前仅支持来自MMA scenarios的日志文件的此类型信息。在您的方案中,不收集SqlParameter中的类型信息;因此,查询中的所有变量都默认为SQL_VARIANT,并带有空值。

答案 1 :(得分:0)

在Visual Studio 2010和SQL Server 2008上使用您的代码我尝试重现您的场景(或者至少我认为您的场景是,因为您不是非常具体)。 我创建了这些表:Q25682067 使用int作为商品ID和#is; isActive'字段;和Q25682067_对于每个字段都有 sql_variant ,如您的帖子所示。

CREATE TABLE [Q25682067]([ID] [int] NOT NULL, [IsActive] [bit] NOT NULL) ON [PRIMARY]
CREATE TABLE [Q25682067_Offers]([ID] [sql_variant] NOT NULL,[IsActive] [sql_variant] NOT NULL ) ON [PRIMARY]

将数据对(1,false)和(1,true)添加到每个表中。 现在考虑你的过滤器是这样的:

var filters = new Parameter[] { 
    new Parameter() {Id="@offerID ", Value=1},
    new Parameter() {Id="@isActive", Value=false}
};

其中参数可能非常迅速(不考虑OOP实践):

internal class Parameter
{
   public string Id;
   public object Value;
}

现在,这会填充数据表:

cmd.CommandText = "select * from Q25682067 where ID = @offerID and IsActive = @isActive";

这不是:

cmd.CommandText = "select * from Q25682067_Offers where ID = @offerID and IsActive = @isActive"; 

使用像这样的SqlParameter构造函数将您的参数绑定到SqlDbType.Int和SqlDbType.Bit而不是SqlDbType.Variant,这似乎是您的首选武器。这就是为什么你的代码使用第一个表定义,而不是第二个。