繁体   English   中英

如何将 Nullable Bit 类型值传递给 SQL Server 存储过程?

[英]How to pass Nullable Bit type value into to SQL Server stored procedure?

我想将null值传递给 where 子句bit类型变量以获取表中的所有行。 但也当我通过truefalse where 子句应该起作用时。

错误:

无法确定条件表达式的类型,因为 'bool?' 之间没有隐式转换和'System.DBNull'

存储过程:

CREATE PROCEDURE [dbo].[SelectAllUIDs] 
    @enable bit
AS
BEGIN
    SET NOCOUNT ON;

    SELECT 
        [UID], [fEnable] [Enable],
        [AddedDate] [Added Date]
    FROM 
        [VehicleService].[dbo].[NFCCard] 
    WHERE
        fEnable = @enable OR fEnable IS NOT NULL
    ORDER BY 
        NfcKy
END

C#代码:

 public DataSet SelectUid(bool? status)
 {
        DataSet ds = new DataSet();

        try
        {
            SqlCommand com = new SqlCommand("SelectAllUIDs", con);
            com.CommandType = CommandType.StoredProcedure;
            com.Parameters.Add(new SqlParameter("@enable", SqlDbType.Bit)
                                   { Value = status != null ? status : DBNull.Value });

            SqlDataAdapter adp = new SqlDataAdapter(com);
            adp.Fill(ds);
        }
        catch (Exception ex)
        {
            ds = null;
            throw ex;
        }
        return ds;
    }

调用:

DataSet ds = SelectUid(null); // should return all rows

DataSet ds = SelectUid(true); // should return fEnable = true rows

DataSet ds = SelectUid(false); // should return fEnable = false rows

你可以使用?? 运算符以在状态为null时提供替代方法。 就像@user2864740 评论的那样,双方都必须是兼容的类型。 这行不通:

var x = true ?? DBNull.Value;  // "no implicit conversion" error

??左手值bool ,但右手值不是。 所以编译器会抱怨DBNull.Value不能“隐式转换”为bool 要解决此问题,请将左侧投射到object

var x = (object) true ?? DBNull.Value;

现在?? 将评估为一个对象,该对象可以包含boolDNull.Value 将其应用于您的问题,您将得到:

com.Parameters.AddWithValue("@parname", (object) status ?? DBNull.Value);

我有一个 Nullable 项目,上面的代码生成编译器警告并使用这种模式

static object Nullable(bool? value)
{
    if (value is null)
        return DBNull.Value;
    else
        return value.Value;
}
static object Nullable(int? value)
{
    if (value is null)
        return DBNull.Value;
    else
        return value.Value;
}

编译器知道要选择什么,以便在编译期间无论我使用多少可空数据类型都可以毫无问题地得到解决。

我的参数我这样声明

com.Parameters.Add(
new SqlParameter("parameterName", SqlDbType.Bit) { Value  = Nullable(visitStat.Interactive), IsNullable=true });

我喜欢尽可能减少反射,而 AddWithValue 会导致 MS 代码中的反射,并且当您在编写代码时知道数据类型时,您通常会在不需要它时在参数化查询中得到错误的数据类型。

使用基于反射的 SQLParameter 构造函数并不太聪明,因为当您这样做时,SQL 服务器会将其转换为执行计划中的正确数据类型,使其成为 Row-By-Row 操作。 使用 TSQL 数据类型(如 SmallDatetime、date、TinyInt、CHAR 和 VarChar 数据类型)时尤其糟糕,因为它们总是出错。

您在传递字符串时会看到这一点,因为它们总是反映在 nvarchar(max) 中,将索引的电子邮件字段与 nvarchar(max) 参数进行比较......看看隐式转换,我们知道它需要的数据类型,几个额外的字符我们需要输入我们的程序代码是值得的,当“他们说”“数据库很慢”时,当它开始比可能适合内存的微型开发人员数据库大时。

仅仅因为您可以在代码中制作 1 行并不能使其具有高性能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM