【问题标题】:Null Reference Exception in SQL Query outputSQL 查询输出中的空引用异常
【发布时间】:2013-06-11 04:20:46
【问题描述】:

在努力从 SQL 数据库中提取某些信息以在 C# 代码中使用以进行一些权限检查后,我决定回归基础并学习如何正确地进行操作,并慢慢提高我的技能,以便最终能够做到我需要做什么。下面代码的目的是获取当前的 Active Directory 用户,然后进入一个包含用户名和其他信息的 SQL 表,找到匹配的,然后将其显示在 MessageBox 中。

string currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

using (var cn = new SqlConnection(ConfigurationManager.ConnectionStrings["HSEProjRegConnectionString1"].ConnectionString))
using (var cmd = new SqlCommand())
{
    cn.Open();
    cmd.Connection = cn;
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = "SELECT username FROM [tbl_Person] WHERE [username] LIKE '@currentUser'";

    SqlParameter param = new SqlParameter();
    cmd.Parameters.Add("@currentUser", SqlDbType.Char).Value = currentUser;

    MessageBox.Show("{0}", Convert.ToString((int)cmd.ExecuteScalar()));

    cn.Close();
}

虽然有些不对劲。我收到以下错误和堆栈跟踪。第 38 行是 MessageBox 行。

System.NullReferenceException:对象引用未设置为对象的实例。

[NullReferenceException: Object reference not set to an instance of an object.]
HSE_project_Register.admin.Page_Load(Object sender, EventArgs e) in S:\IT\Development\Visual Studio Projects\HSE Project Register\admin\admin.aspx.cs:38
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3064

是什么导致该代码中出现空引用异常?如果答案在堆栈跟踪中,有人可以向我解释一下吗?我发现堆栈跟踪非常混乱。

【问题讨论】:

标签: c# .net sql-server ado.net nullreferenceexception


【解决方案1】:

您需要将查询更改为类似

SELECT username FROM [tbl_Person] WHERE [username] LIKE '%' + @currentUser + '%'

另外,你得到的不是转换异常,而是空引用异常。

所以你需要告诉我们页面 admin.aspx.cs 的第 38 行是什么?

为什么不把查询改成类似

SELECT COUNT(username) as Cnt_UserName 
FROM [tbl_Person] 
WHERE [username] LIKE '%' + @currentUser + '%'

应该总是返回一个 Int

我认为问题出在SqlDbType.Char 类型上。尝试将其更改为 SqlDbType.VarChar

看看下面的演示

SQL Fiddle DEMO

来自LIKE (Transact-SQL)

使用包含 char 和 varchar 的模式进行字符串比较 由于数据的存储方式,数据可能无法通过 LIKE 比较。

【讨论】:

  • 我做了,Messagebox 行是MessageBox.Show("{0}", Convert.ToString((int)cmd.ExecuteScalar()));
  • 感谢您的回复,非常感谢。
【解决方案2】:

你的sql语句有问题

LIKE '@currentUser'"

这不会被识别为参数,你最好如下所示

cmd.CommandText = "SELECT username FROM [tbl_Person] WHERE [username] LIKE @currentUser";

当你设置参数时

 cmd.Parameters.AddWithValue("@currentUser", '%' + currentUser + '%');

【讨论】:

    【解决方案3】:

    您收到此异常是因为返回的值来自:

    (int)cmd.ExecuteScalar()
    

    实际上是null。然而,这里最让我感兴趣的是这个。您的查询显示:

    SELECT username FROM [tbl_Person]...
    

    但随后您将获取结果并尝试将其转换为int。我觉得不对。看来这个Convert.ToString((int)cmd.ExecuteScalar()) 实际上应该是这个cmd.ExecuteScalar() as string。这既可以处理null,也可以正确地转换其类型。

    要修复您的查询,请考虑以下代码:

    cmd.CommandText = "SELECT username FROM [tbl_Person] WHERE [username] LIKE @currentUser";
    
    cmd.Parameters.AddWithValue("@currentUser", "%" + currentUser + "%";
    

    【讨论】:

    • 哦,那是有道理的。这是否意味着我的 Query 不正确,因为它是为了输出一些我稍后将用于在 C# 中进行比较的内容?
    • @Trido,请查看我的编辑并回复。查询和您的代码似乎对我不屑一顾。
    • 这确实有效,虽然没有显示任何内容,但它已经修复了我的错误。我认为这可能与类型转换有关,但老实说,我一直在努力将其转换为字符串。这很好地解决了这个问题,并且更容易阅读。我只是将它设置为标签,而不是 MessageBox,因为这样更容易。标签是空白的,这很好,因为您是对的,它返回了 null。我只需要弄清楚查询出了什么问题,因为我希望它输出用户名,假设它当然是查询。
    • @Trido,太棒了。很高兴能为您提供帮助!
    • @Trido,请查看我的编辑以帮助您使查询正常工作。
    猜你喜欢
    • 2011-01-25
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 2016-05-11
    • 1970-01-01
    • 2011-04-06
    • 2018-06-17
    相关资源
    最近更新 更多