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

使用.NET C#操作数据库报错:关键字'User'附近语法不正确

问题描述

我编写了一段.NET C#代码用于SQL Server数据库操作,实现用户名存在性校验及新账户插入功能,代码如下:

try
{
    //insert data into database
    //check if data already exists
    using (SqlConnection con = new SqlConnection(@"Server=DESKTOP-31579CJ\SQLEXPRESS;Database=LoginInformation;Trusted_connection = True;"))
    { 
        SqlCommand cmd = new SqlCommand(@"SELECT User.Username FROM User WHERE Username = '" + Username.Text + "'", con);
        con.Open();
        SqlDataReader dr = cmd.ExecuteReader();
        if (dr.Read())
        {
            MessageBox.Show("Username already exists");
        }
        else
        {
            MessageBox.Show("Account created");
            cmd = new SqlCommand(@"INSERT INTO User (Username,Password) VALUES ('" + Username.Text + "','" + Password.Password + "')", con);

            cmd.ExecuteNonQuery();
            //clear textboxes
            Username.Text = "";
            Password.Password = "";
        }
        dr.Close();
        con.Close();
    }
}
catch (Exception ex)
{
    MessageBox.Show("Exception occured" + ": " + ex.Message);
    SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-31579CJ\SQLEXPRESS;Initial Catalog=LoginInformation;Integrated Security=True;User ID = yes; Password = yes");
    //create table if one does not exist
    SqlCommand cmd = new SqlCommand("CREATE TABLE User (Username varchar(50), Password varchar(50))", con);
}

执行代码时抛出异常:

Incorrect syntax near the keyword 'User'

由于很少使用C#和SQL,无法定位问题所在,希望能得到问题排查及代码优化的相关反馈。

问题排查与优化方案

1. 核心异常原因:SQL保留关键字冲突

User是SQL Server的保留关键字,直接用作表名会导致语法解析错误。解决方法是用方括号[User]包裹表名,让SQL引擎将其识别为普通表名。

2. 紧急修复:消除SQL注入风险

原代码使用字符串拼接生成SQL语句,这是极其危险的做法,攻击者可以通过输入恶意字符串篡改SQL逻辑(比如输入' OR 1=1 --直接绕过校验甚至篡改数据)。必须改用参数化查询:

  • 使用SqlCommand.Parameters.Add方法传递参数,避免字符串拼接
  • 参数化查询还能自动处理特殊字符转义,避免语法错误

3. 代码逻辑与资源管理优化

  • 连接自动释放:using块会自动调用SqlConnection.Dispose(),无需手动调用con.Close()
  • DataReader资源管理:将SqlDataReader也放入using块,自动释放资源,避免内存泄漏
  • 异常处理修正:原catch块中创建表的逻辑存在问题——未打开连接就执行命令,且连接字符串重复;创建表的逻辑应该在程序初始化时执行,而非异常触发时
  • 密码存储安全:明文存储密码是严重安全漏洞,必须使用哈希算法(如SHA256、BCrypt)对密码进行哈希后存储

优化后的完整代码

using System.Data.SqlClient;
using System.Security.Cryptography;
using System.Text;

// 建议将连接字符串放在配置文件中,而非硬编码
private const string ConnectionString = @"Server=DESKTOP-31579CJ\SQLEXPRESS;Database=LoginInformation;Trusted_Connection=True;";

private void CreateUserTableIfNotExists()
{
    // 初始化时创建表(仅执行一次)
    using (SqlConnection con = new SqlConnection(ConnectionString))
    {
        string createTableSql = @"IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'User')
                                 CREATE TABLE [User] (Username varchar(50) PRIMARY KEY, PasswordHash varchar(64))";
        using (SqlCommand cmd = new SqlCommand(createTableSql, con))
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
    }
}

private bool IsUsernameExists(string username)
{
    using (SqlConnection con = new SqlConnection(ConnectionString))
    {
        string checkSql = @"SELECT 1 FROM [User] WHERE Username = @Username";
        using (SqlCommand cmd = new SqlCommand(checkSql, con))
        {
            cmd.Parameters.AddWithValue("@Username", username);
            con.Open();
            return cmd.ExecuteScalar() != null;
        }
    }
}

private string HashPassword(string password)
{
    // 使用SHA256哈希密码(生产环境推荐使用BCrypt等带盐的哈希算法)
    using (SHA256 sha256 = SHA256.Create())
    {
        byte[] bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
        StringBuilder builder = new StringBuilder();
        foreach (byte b in bytes)
        {
            builder.Append(b.ToString("x2"));
        }
        return builder.ToString();
    }
}

private void CreateAccount()
{
    // 先确保表存在
    CreateUserTableIfNotExists();

    string username = Username.Text.Trim();
    string password = Password.Password;

    if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
    {
        MessageBox.Show("请输入用户名和密码");
        return;
    }

    if (IsUsernameExists(username))
    {
        MessageBox.Show("用户名已存在");
        return;
    }

    try
    {
        string passwordHash = HashPassword(password);
        using (SqlConnection con = new SqlConnection(ConnectionString))
        {
            string insertSql = @"INSERT INTO [User] (Username, PasswordHash) VALUES (@Username, @PasswordHash)";
            using (SqlCommand cmd = new SqlCommand(insertSql, con))
            {
                cmd.Parameters.AddWithValue("@Username", username);
                cmd.Parameters.AddWithValue("@PasswordHash", passwordHash);
                con.Open();
                cmd.ExecuteNonQuery();
            }
        }

        MessageBox.Show("账户创建成功");
        // 清空输入框
        Username.Text = "";
        Password.Password = "";
    }
    catch (Exception ex)
    {
        MessageBox.Show($"创建失败:{ex.Message}");
    }
}

额外说明

  • 连接字符串管理:建议将连接字符串放入app.config或appsettings.json中,便于维护和修改
  • 哈希算法选择:SHA256是单向哈希,但仍推荐使用带随机盐的算法(如BCrypt、Argon2),防止彩虹表攻击
  • 输入验证:增加了用户名和密码的非空校验,避免无效数据插入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:01:16