ASP.NET图书馆项目中SqlDataReader相关SQL查询故障求助
解决你的图书馆项目SQL查询问题
嘿,看你这段代码的问题,大概率是直接字符串拼接SQL导致的语法错误+严重的SQL注入风险,咱们立马给你修正过来,顺便说说为啥原来的写法不行:
原代码的核心问题
你直接把LstAuthor.SelectedItem.Text拼进SQL语句里,如果作者名字里包含单引号(比如O'Conner这种),SQL语法直接就崩了;而且这种写法完全没有防注入,恶意用户可以通过构造特殊文本直接篡改你的数据库,风险极高。
修正后的参数化查询写法
这才是ADO.NET里正确的数据库操作姿势,既安全又能避免语法错误:
protected void btnAdd_Click(object sender, EventArgs e) { lblEMsg.Visible = false; string Author_ID, Publisher_ID, Category_ID, Supplier_ID; try { // 1. 用参数占位符代替直接拼接文本 string getAuthorIdSql = "SELECT Author_ID FROM Author WHERE Author_Name = @AuthorName"; // 2. 用using包裹资源,自动释放连接/命令/阅读器,避免泄漏 using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["YourLibraryConn"].ConnectionString)) { conn.Open(); // 查询作者ID using (SqlCommand cmd = new SqlCommand(getAuthorIdSql, conn)) { // 3. 添加参数,指定类型更严谨(也可以简化为cmd.Parameters.AddWithValue,但指定类型更安全) cmd.Parameters.Add("@AuthorName", SqlDbType.NVarChar, 100).Value = LstAuthor.SelectedItem.Text; using (SqlDataReader sdr = cmd.ExecuteReader()) { if (sdr.Read()) { Author_ID = sdr["Author_ID"].ToString(); // 这里可以继续写查询出版社、分类、供应商ID的逻辑,同样要用参数化! // 比如查询Publisher_ID的话,也是类似的参数化写法,别再拼接字符串了 } else { // 处理找不到作者的情况 lblEMsg.Visible = true; lblEMsg.Text = "未找到指定的作者信息"; } } } } } catch (Exception ex) { lblEMsg.Visible = true; // 调试阶段可以显示详细错误,上线后换成友好提示 lblEMsg.Text = $"操作失败:{ex.Message}"; } }
关键改进点说明
- 参数化查询:用
@AuthorName这种占位符,让ADO.NET自动处理字符串转义,彻底杜绝SQL注入,同时解决特殊字符导致的语法错误。 - using语句:SqlConnection、SqlCommand、SqlDataReader都是需要手动释放的资源,用using会在代码块结束时自动调用Dispose,避免数据库连接泄漏。
- 结果判断:增加
if (sdr.Read())的判断,避免没找到数据时读取Author_ID出现空值异常。 - 明确的错误提示:catch块里捕获异常并显示,方便你快速定位问题。
另外提醒下:你代码里的Profile pro = new Profile();如果是用来获取连接字符串的,记得把上面代码里的YourLibraryConn换成你实际的连接字符串名称(从Web.config的<connectionStrings>里找)。
内容的提问来源于stack exchange,提问作者Gwiza Erick
相关产品推荐
相关产品推荐

