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

使用C#向SQL Server插入数据时出现语法错误,求正确实现方法

问题排查与正确实现指南

嘿,我一眼就看到你代码里的问题了,咱们一步步拆解解决:

核心错误原因

你遇到的语法错误,根源在于错误的SQL语句构建方式,还有几个细节问题:

  1. string.Format的参数顺序完全搞反了:你把productname作为第一个参数传给string.Format,这相当于用产品名称当模板去格式化其他参数,而且你根本没把格式化后的字符串赋值给command.CommandText——导致执行的SQL语句里还是{0}、{1}这些占位符,数据库根本不认识它们,直接触发语法错误。
  2. 用字符串拼接SQL的方式本身就有致命问题:不仅会因为特殊字符(比如产品名里的单引号O'Neil)触发语法错误,还会暴露在SQL注入攻击的风险下,这是绝对要避免的。

正确的实现方式(参数化查询)

行业标准的做法是使用参数化查询,既安全又能避免各种语法问题,下面是修改后的完整代码:

1. 优化后的InsertProduct方法

static void InsertProduct(string productname, int productstock, int productcategoryid, int productemployeeid)
{
    // 用using包裹SqlConnection,确保连接自动释放,不用手动Close
    using (SqlConnection conn = new Database().connection())
    {
        // 参数化SQL语句,用@前缀定义参数
        string sql = @"INSERT INTO Products (ProductName, ProductStock, ProductCategoryID, ProductEmployeeID) 
                       VALUES (@ProductName, @ProductStock, @ProductCategoryID, @ProductEmployeeID)";
        
        using (SqlCommand command = new SqlCommand(sql, conn))
        {
            // 逐个添加参数,指定类型和值(匹配数据库字段类型)
            command.Parameters.Add("@ProductName", SqlDbType.NVarChar, 32).Value = productname;
            command.Parameters.Add("@ProductStock", SqlDbType.Int).Value = productstock;
            command.Parameters.Add("@ProductCategoryID", SqlDbType.Int).Value = productcategoryid;
            command.Parameters.Add("@ProductEmployeeID", SqlDbType.Int).Value = productemployeeid;
            
            // 数据库里ProductCreatedDate已经设置了DEFAULT GETDATE(),所以不用手动传值
            conn.Open();
            command.ExecuteNonQuery();
        }
    }
}

2. 主方法的健壮性优化

原来的int.Parse如果遇到非数字输入会直接崩溃,建议换成int.TryParse:

static void Main(string[] args)
{
    while (true)
    {
        Console.Write("Indtast Produktnavn :");
        string productname = Console.ReadLine();

        Console.Write("Hvor mange er der på lager? : ");
        if (!int.TryParse(Console.ReadLine(), out int productstock))
        {
            Console.WriteLine("Ugyldigt tal, prøv igen!");
            continue;
        }

        Console.Write("Hvilken kategori ID hører produktet til? : ");
        if (!int.TryParse(Console.ReadLine(), out int productcategoryid))
        {
            Console.WriteLine("Ugyldigt tal, prøv igen!");
            continue;
        }

        Console.Write("Hvilket medarbejder ID har oprettet produktet? : ");
        if (!int.TryParse(Console.ReadLine(), out int productemployeeid))
        {
            Console.WriteLine("Ugyldigt tal, prøv igen!");
            continue;
        }

        try
        {
            InsertProduct(productname, productstock, productcategoryid, productemployeeid);
            Console.WriteLine("Produktet er tilføjet!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Fejl: {ex.Message}");
            Console.ReadKey();
        }
    }
}

3. 可选:用Product类封装插入逻辑(面向对象风格)

如果想更贴合面向对象设计,可以修改InsertProduct接收Product对象:

static void InsertProduct(Product product)
{
    using (SqlConnection conn = new Database().connection())
    {
        string sql = @"INSERT INTO Products (ProductName, ProductStock, ProductCategoryID, ProductEmployeeID, ProductCreatedDate) 
                       VALUES (@ProductName, @ProductStock, @ProductCategoryID, @ProductEmployeeID, @ProductCreatedDate)";
        
        using (SqlCommand command = new SqlCommand(sql, conn))
        {
            command.Parameters.Add("@ProductName", SqlDbType.NVarChar, 32).Value = product.ProductName;
            command.Parameters.Add("@ProductStock", SqlDbType.Int).Value = product.ProductStock;
            command.Parameters.Add("@ProductCategoryID", SqlDbType.Int).Value = product.ProductCategoryID;
            command.Parameters.Add("@ProductEmployeeID", SqlDbType.Int).Value = product.ProductEmployeeID;
            command.Parameters.Add("@ProductCreatedDate", SqlDbType.DateTime).Value = product.ProductCreatedDate;
            
            conn.Open();
            command.ExecuteNonQuery();
        }
    }
}

主方法里调用时:

Product newProduct = new Product(productname, productstock, productcategoryid, productemployeeid);
InsertProduct(newProduct);

关键注意事项

  • 永远使用参数化查询:绝对不要用字符串拼接构建SQL,这是预防SQL注入和语法错误的核心手段。
  • 用using管理资源:SqlConnection、SqlCommand都实现了IDisposable接口,using语句会自动帮你释放资源,避免连接泄漏。
  • 利用数据库默认值:像ProductCreatedDate这样的字段,交给数据库用GETDATE()生成,既能减少代码逻辑,还能避免客户端和服务器时间不一致的问题。
  • 处理无效输入:用TryParse代替Parse,让程序更健壮,不会因为用户输入错误直接崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:47:33