You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从Permissions表拉取数据:C#&SQL空引用异常求助

问题分析与解决方案

核心错误原因

  1. 数组未初始化:string[] Data;仅声明了数组但未分配内存空间,直接给Data[0]等下标赋值时必然触发NullReferenceException。
  2. SQL语句错误:Emp_ID是INT类型,SQL中用单引号包裹会导致类型不匹配,同时直接拼接参数存在严重的SQL注入风险。
  3. 未处理DBNull场景:数据库字段可能为NULL,直接强制类型转换会引发异常。

修正方案

1. 初始化存储容器

如果坚持用数组,需提前指定长度;更推荐用List<string>或自定义权限类存储,灵活性和可维护性更强。

2. 使用参数化查询

彻底解决SQL注入和类型不匹配问题,同时提升代码安全性。

3. 用using自动管理资源

替代手动关闭连接、阅读器的操作,避免资源泄漏。


修正后的代码(用List<string>存储)

namespace TMS
{
    public partial class Login_Form : Form
    {
        // 初始化List用于存储权限数据
        List<string> PermissionsList = new List<string>();
        
        void verify()
        {
            // 用using自动释放SqlCommand资源
            using (SqlCommand cmd = new SqlCommand("SELECT Check_Out, Check_In, Self_His_Tool, Self_His_User, Tool_His, User_His, Add_Users, Add_Tools, Remove_Users, Remove_Tools FROM Permissions WHERE Emp_ID = @Emp_ID", Con))
            {
                // 添加参数匹配INT类型,避免SQL注入
                cmd.Parameters.AddWithValue("@Emp_ID", Settings.Emp_ID);
                
                try
                {
                    Con.Open();
                    // 用using自动释放SqlDataReader资源
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            // 逐个读取字段,处理DBNull情况,默认赋值为"False"
                            PermissionsList.Add(rdr.IsDBNull(0) ? "False" : rdr.GetString(0));
                            PermissionsList.Add(rdr.IsDBNull(1) ? "False" : rdr.GetString(1));
                            PermissionsList.Add(rdr.IsDBNull(2) ? "False" : rdr.GetString(2));
                            PermissionsList.Add(rdr.IsDBNull(3) ? "False" : rdr.GetString(3));
                            PermissionsList.Add(rdr.IsDBNull(4) ? "False" : rdr.GetString(4));
                            PermissionsList.Add(rdr.IsDBNull(5) ? "False" : rdr.GetString(5));
                            PermissionsList.Add(rdr.IsDBNull(6) ? "False" : rdr.GetString(6));
                            PermissionsList.Add(rdr.IsDBNull(7) ? "False" : rdr.GetString(7));
                            PermissionsList.Add(rdr.IsDBNull(8) ? "False" : rdr.GetString(8));
                            PermissionsList.Add(rdr.IsDBNull(9) ? "False" : rdr.GetString(9));
                        }
                    }
                }
                finally
                {
                    // 确保连接关闭
                    if (Con != null && Con.State == ConnectionState.Open)
                        Con.Close();
                }
            }
        }
    }
}

更规范的实现:自定义权限类

如果后续需要单独调用某个权限项,用类存储会更清晰直观:

// 定义权限实体类
public class UserPermissions
{
    public int Emp_ID { get; set; }
    public bool CheckOut { get; set; }
    public bool CheckIn { get; set; }
    public bool SelfHisTool { get; set; }
    public bool SelfHisUser { get; set; }
    public bool ToolHis { get; set; }
    public bool UserHis { get; set; }
    public bool AddUsers { get; set; }
    public bool AddTools { get; set; }
    public bool RemoveUsers { get; set; }
    public bool RemoveTools { get; set; }
}

// 修正后的verify方法
namespace TMS
{
    public partial class Login_Form : Form
    {
        UserPermissions CurrentUserPermissions;
        
        void verify()
        {
            CurrentUserPermissions = new UserPermissions();
            
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM Permissions WHERE Emp_ID = @Emp_ID", Con))
            {
                cmd.Parameters.AddWithValue("@Emp_ID", Settings.Emp_ID);
                
                try
                {
                    Con.Open();
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.Read())
                        {
                            CurrentUserPermissions.Emp_ID = rdr.GetInt32(rdr.GetOrdinal("Emp_ID"));
                            // 将数据库中的文本类型True/False转为bool值,处理DBNull
                            CurrentUserPermissions.CheckOut = rdr.IsDBNull(rdr.GetOrdinal("Check_Out")) ? false : rdr.GetString(rdr.GetOrdinal("Check_Out")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.CheckIn = rdr.IsDBNull(rdr.GetOrdinal("Check_In")) ? false : rdr.GetString(rdr.GetOrdinal("Check_In")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.SelfHisTool = rdr.IsDBNull(rdr.GetOrdinal("Self_His_Tool")) ? false : rdr.GetString(rdr.GetOrdinal("Self_His_Tool")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.SelfHisUser = rdr.IsDBNull(rdr.GetOrdinal("Self_His_User")) ? false : rdr.GetString(rdr.GetOrdinal("Self_His_User")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.ToolHis = rdr.IsDBNull(rdr.GetOrdinal("Tool_His")) ? false : rdr.GetString(rdr.GetOrdinal("Tool_His")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.UserHis = rdr.IsDBNull(rdr.GetOrdinal("User_His")) ? false : rdr.GetString(rdr.GetOrdinal("User_His")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.AddUsers = rdr.IsDBNull(rdr.GetOrdinal("Add_Users")) ? false : rdr.GetString(rdr.GetOrdinal("Add_Users")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.AddTools = rdr.IsDBNull(rdr.GetOrdinal("Add_Tools")) ? false : rdr.GetString(rdr.GetOrdinal("Add_Tools")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.RemoveUsers = rdr.IsDBNull(rdr.GetOrdinal("Remove_Users")) ? false : rdr.GetString(rdr.GetOrdinal("Remove_Users")).Equals("True", StringComparison.OrdinalIgnoreCase);
                            CurrentUserPermissions.RemoveTools = rdr.IsDBNull(rdr.GetOrdinal("Remove_Tools")) ? false : rdr.GetString(rdr.GetOrdinal("Remove_Tools")).Equals("True", StringComparison.OrdinalIgnoreCase);
                        }
                    }
                }
                finally
                {
                    if (Con != null && Con.State == ConnectionState.Open)
                        Con.Close();
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Ablac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:05:19