从SQL Server表中选择NULL值

本文关键字:选择 NULL SQL Server | 更新日期: 2023-09-27 18:29:33

我正在使用C#和SQL Server 使用ASP.NET MVC 4

我正在从下表中选择一行数据

CREATE TABLE [dbo].[Mem_Basic] (
[Id]          INT           IDENTITY (1, 1) NOT NULL,
[Mem_NA]      VARCHAR (100) NOT NULL,
[Mem_Occ]     VARCHAR (200) NOT NULL,
[Mem_Role]    VARCHAR (200) NOT NULL,
[Mem_Email]   VARCHAR (50)  NULL,
[Mem_MPh]     VARCHAR (15)  NULL,
[Mem_DOB]     DATE          NULL,
[Mem_BGr]     NCHAR (10)    NULL,
[Mem_WAnn]    DATE          NULL,
[Mem_Spouse]  VARCHAR (75)  NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);

使用以下代码

public MemberBasicData GetMemberProfile(int id)
{
        MemberBasicData mb = new MemberBasicData();
        using (SqlConnection con = new SqlConnection(Config.ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM Mem_Basic WHERE Id="+id+"", con))
            {
                try
                {
                    con.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                   if(reader.Read()==true)
                    {
                        mb.Id = (int)reader["Id"];
                        mb.Mem_NA = (string)reader["Mem_NA"];
                        mb.Mem_Occ = (string)reader["Mem_Occ"];
                        mb.Mem_Role = (string)reader["Mem_Role"];
                        mb.Mem_Email = (string)reader["Mem_Email"];
                        mb.Mem_MPh = (string)reader["Mem_MPh"];
                        mb.Mem_DOB = (Convert.ToDateTime(reader["Mem_DOB"]));
                        mb.Mem_BGr = (string)reader["Mem_BGr"];
                        mb.Mem_WAnn = (Convert.ToDateTime(reader["Mem_WAnn"]));
                        mb.Mem_Spouse = (string)reader["Mem_Spouse"];
                   }
                }
                catch (Exception e) { throw e; }
                finally { if (con.State == System.Data.ConnectionState.Open) con.Close(); }
            } 
        }
        return mb;
    }

这显示错误

无法将"System.DBNull"类型的对象强制转换为"System.String"类型。

Mem_EmailMPh...等有时包含NULL值。如果该值为null,我希望返回null)。任何人都请帮帮我。

从SQL Server表中选择NULL值

只要做一些简短的if,就应该对所有其他变量做同样的操作:

 mb.Mem_Email = reader["Mem_Email"] == System.DBNull.Value ? null : (string) reader["Mem_Email"];

使用dapper这样的工具可以省去大量的痛苦(http://www.nuget.org/packages/Dapper):

public MemberBasicData GetMemberProfile(int id)
{
    using (var con = new SqlConnection(Config.ConnectionString))
    {
        return con.Query<MemberBasicData>(
            "SELECT * FROM Mem_Basic WHERE Id=@id",
            new { id } // full parameterization, done the easy way
        ).FirstOrDefault();
    }
}

它的作用:

  • 进行了正确的参数化(为了性能和安全),但没有任何不便
  • 为您执行所有的具体化,处理null(参数和列中)
  • 是疯狂优化的(基本上,它的速度与自己编写所有代码的速度相当,只是出错的地方更少)

除了King King的答案,您还可以编写这样的代码:

mb.Mem_Email = reader["Mem_Email"] as string;

对于值类型,如果列允许null,那么在C#中将它们映射到可为null的值类型是一种很好的做法,这样代码reader["Mem_DOB"] as DateTime?就可以在中工作

更改所有列,该中可能为NULL

mb.Mem_NA = (string)reader["Mem_NA"];

mb.Mem_NA = reader["Mem_NA"].ToString();

处理可为null的字段:

mb.Mem_Email = System.DBNull.Value.Equals(reader["Mem_Email"])?"":
                                      (string)reader["Mem_Email"];

执行相同的操作:兆字节Mem_MPh,mb。Mem_BGr和mb。Mem_Spouse。

我的意思不是听起来像SQL偏执狂(当然,这意味着我DO的意思是听起来像SQL偏见),但如果你遵循SQL最佳实践,使用列列表而不是SELECT*,你可以通过在可为null的列上使用COALESCE来解决这个问题,因此:

SELECT
  [Id],
  [Mem_NA],
  [Mem_Occ],
  [Mem_Role],
  COALESCE( [Mem_Email], '' ) AS [Mem_Email],
  COALESCE( [Mem_MPh], '' ) AS [Mem_MPh],
  COALESCE( [Mem_DOB], CAST( '1753-1-1' AS DATE ) ) AS [Mem_DOB],
  COALESCE( [Mem_BGr, '' ) AS [Mem_BGr],
  COALESCE( [Mem_WAnn], CAST( '1753-1-1' AS DATE ) ) AS [Mem_WAnn],
  COALESCE( [Mem_Spouse], '' ) AS [Mem_Spouse]
FROM 
  [dbo].[Mem_Basic];

您的c#代码现在可以可靠地处理结果集,而不必考虑异常值(日期除外;您可能应该检查COALESCE中使用的默认值(我在上面的示例中使用了SQL Date变量的最小允许值),并适当地处理它们。

此外,您还可以在c#代码中去掉finally块。您将连接封装在"using"块中;当您超出范围时,它将自动关闭连接(这就是"使用"块的目的)。