2016-01-31 87 views
2

我试图创建一个需要4个参数的存储过程。这4个参数决定了返回的表的外观。传递Nullable整数(int?SomeValue = NULL)作为参数存储过程

@C_ID参数始终为数字。 @U_ID@P_ID值可以包含有效的数值,或者可以(或应该)作为NULL传递,因此WHERE条件可以执行或不执行。

ALTER PROCEDURE [dbo].[GetData] 
    @C_ID integer, 
    @U_ID integer = Null, 
    @P_ID integer = Null, 
    @SortIndex integer = 1 
AS 
BEGIN 
    SELECT 
     ID, P_ID, U_Name, P_Name, 
     FORMAT(Date_When, 'dd/MM/yyyy hh:mm tt') 
    FROM 
     SomeTable 
    WHERE 
     C_ID = @C_ID 
     AND (@P_ID IS NULL OR P_ID = @P_ID) 
     AND (@U_ID IS NULL OR U_ID = @U_ID) 
    ORDER BY 
     CASE WHEN @SortIndex = 1 THEN -ID 
      ELSE ID 
     END ASC 
END 

在SQL服务器2014以下的执行工作得很好,没有任何错误:

exec GetData '15', null, null, '1'; 
exec GetData '15', '1', null, '1'; 
exec GetData '15', null, '1', '1'; 
exec GetData '15', '1', '1', '1'; 
... 

但是在C#侧下面的代码无法执行:

int? SomeValue = null; 
Adapter = new SqlDataAdapter("exec GetData '15'," + SomeValue + ",null,'1';", Connection); 
Adapter.Fill(Data); 

这给了我一个错误

靠近','的语法不正确, 。

如果我将SomeValue变量更改为1,它可以很好地工作。

DBNull.Value并且简单地将参数保留为“'也不起作用。

所以问题是:我将如何(如果可能的话)能够将可空的整数传递给SQL,因为它可以是空值和有效数字?

+3

[请不要与构建串联SQL查询(http://stackoverflow.com/q/332365/11683)。 – GSerg

+0

至于你的问题的正式答案,这是因为'SomeValue',是'null',在结果字符串中插入一个空字符串,这将导致后面的两个逗号。 – GSerg

回答

4

做一些沿着这些线路:

Adapter = new SqlDataAdapter(); 

//con is an open SQLConnection 
var cmd = new SQLCommand("GetData", con); 
cmd.Parameters.Add(new SqlParameter("@C_ID", 15)); 
cmd.Parameters.Add(new SqlParameter("@U_ID", SomeValue ?? DBNull.Value)); 
cmd.Parameters.Add(new SqlParameter("@P_ID", SomeValue ?? DBNull.Value)); 
cmd.Parameters.Add(new SqlParameter("@SortIndex", 1)); 
cmd.CommandType = CommandType.StoredProcedure; 
Adapter.SelectCommand = cmd; 
Adapter.Fill(Data); 

??被称为空合并运算符,并检查是否SomeValue为null。如果是这样,背后的价值?被使用 - 在你的情况下DBNull.Value

正如GSerg已经指出的那样,请始终将Little Bobby Tables放在脑后。

编辑:Null-coalescing reference

+0

非常感谢,我不认为我遇到过?操作员之前。 – OverflowStack

+0

运营商'??'不能应用于'int?'类型的操作数和'System.DBNull' 如果我将它更改为SomeValue? (对象)DBNull.Value我得到:ExecuteReader:CommandText属性尚未初始化 – OverflowStack

+0

哦,我忘了将有效的连接传递到SQLCommand。你需要这样做:'var cmd = new SQLCommand(“GetData”,con);''其中'con'是一个开放的'SQLConnection'。这加上将DBNull.Value强制转换为对象,就像你已经做过的那样,应该做到这一点。 – Marco

1

你试过类似下面的东西吗?

SomeValue ?? "null"