使用System.Data.SqlClient向数据库插入产品失败的排查求助
咱们一步步拆解你遇到的问题,数据没插入还触发Main里的Input error提示,核心是代码里的几个关键细节没处理好:
1. SqlParameter参数名缺失@符号
你在AddProduct方法里给日期参数命名时写的是"ProductCreatedDate",但SQL语句里的参数是@ProductCreatedDate——少了开头的@符号会让SQL引擎找不到对应参数值,直接抛出异常,这也是触发Main通用catch块的核心原因。
2. 日期参数无需转成字符串
ProductCreatedDate是数据库的DateTime类型,直接传DateTime.Now即可。你把它转成字符串不仅多余,还可能因为数据库日期格式设置不同导致类型转换错误。
3. 数据库连接未用using自动管理
你的connection()方法返回SqlConnection后,没有用using包裹,手动调用conn.Close()的话,如果中间抛出异常,Close语句根本执行不到,会导致连接泄漏。同时SqlCommand也应该用using确保资源自动释放。
4. 异常捕获范围太窄
AddProduct里只捕获了ArgumentException,但数据库操作可能抛出SqlException、InvalidOperationException等多种异常,这些都会绕过你的catch块,直接跑到Main的通用catch里,让你只能看到毫无帮助的Input error提示。
5. INSERT语句最好明确指定列名
虽然ProductID是自增列,但明确写出要插入的列名(INSERT INTO Products (ProductName, ProductCreatedDate) VALUES(...))会让代码更清晰,后续表结构变更时也不会因为列数不匹配报错。
修正后的完整代码
Database类(优化命名规范)
public class Database { public SqlConnection GetConnection() { SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); builder.DataSource = "DESKTOP-UPVVOJP"; builder.InitialCatalog = "Lagersystem"; builder.IntegratedSecurity = true; return new SqlConnection(builder.ToString()); } }
AddProduct方法
static void AddProduct(string name) { Database db = new Database(); // 用using自动管理连接的打开与释放 using (SqlConnection conn = db.GetConnection()) { // 明确指定INSERT的目标列 string sql = "INSERT INTO Products (ProductName, ProductCreatedDate) VALUES(@ProductName, @ProductCreatedDate)"; using (SqlCommand command = new SqlCommand(sql, conn)) { command.Parameters.Add(new SqlParameter("@ProductName", name)); // 直接传入DateTime类型参数,无需转字符串 command.Parameters.Add(new SqlParameter("@ProductCreatedDate", DateTime.Now)); conn.Open(); int affectedRows = command.ExecuteNonQuery(); Console.WriteLine($"{name} Tilføjet,影响行数:{affectedRows}"); } } }
Main方法(优化异常提示)
static void Main(string[] args) { while (true) { Console.WriteLine("INPUT ProductName :"); string input = Console.ReadLine(); // 先校验输入有效性,避免无效调用 if (string.IsNullOrWhiteSpace(input)) { Console.WriteLine("产品名称不能为空!"); continue; } try { AddProduct(input); Console.WriteLine("Product created!"); } catch (Exception ex) { // 输出具体异常信息,方便调试定位 Console.WriteLine($"错误信息:{ex.Message}"); if (ex.InnerException != null) { Console.WriteLine($"内部错误详情:{ex.InnerException.Message}"); } Console.ReadKey(); } } }
额外调试建议
如果修改后仍有问题,可以在Main的catch块里输出完整异常堆栈(Console.WriteLine(ex.ToString());),这样能精准定位到出错的代码行和底层原因。
内容的提问来源于stack exchange,提问作者user5265806

