如何从URL获取JSON数据写入SQL?代码运行失败求排查
代码问题排查:从JSON获取数据写入SQL失败
问题场景
从指定URL获取JSON数据,已在数据库创建对应列,尝试将数据写入SQL但代码无法运行,代码如下:
public async Task<IEnumerable<Inserch>> GetMaskmapdata() { string targetURI = "https://quality.data.gov.tw/dq_download_json.php?nid=116285&md5_url=53a72b2dcfdd9ecae43afda4b86089be"; HttpClient client = new HttpClient(); client.MaxResponseContentBufferSize = Int32.MaxValue; var response = await client.GetStringAsync(targetURI); var pharmacy = JsonConvert.DeserializeObject<List<Inserch>>(response); SqlConnection connection = new SqlConnection(connstr); connection.Open(); string listvalue = string.Join(",", pharmacy); string sql = "Insert into pharmacy(ID,Name,Address,Phonenumber) values(@ID,@Name,@Address,@Phonenumber)"; SqlCommand cmd = new SqlCommand(sql, connection); foreach (var item in pharmacy) { cmd.Parameters.AddWithValue("@ID", item.ID); cmd.Parameters.AddWithValue("@Name", item.Name); cmd.Parameters.AddWithValue("@Address", item.Address); cmd.Parameters.AddWithValue("@Phonenumber", item.Phonenumber); cmd.ExecuteNonQuery(); connection.Close(); } return pharmacy; }
核心问题点
- 连接提前关闭:
foreach循环第一次迭代就执行connection.Close(),后续循环执行ExecuteNonQuery()时连接已关闭,直接抛出异常。 - 重复添加参数:每次循环都向同一个
SqlCommand实例添加同名参数,第二次循环会触发参数已存在的异常。 - 资源未释放:
HttpClient、SqlConnection、SqlCommand未用using语句管理,易造成资源泄漏,尤其是HttpClient重复创建会耗尽套接字资源。 - 冗余代码:
string listvalue = string.Join(",", pharmacy);未被使用,属于无效代码。 - 无异常处理:缺少网络请求、JSON反序列化、数据库操作的异常捕获,无法定位具体错误原因。
修复后的示例代码
public async Task<IEnumerable<Inserch>> GetMaskmapdata() { string targetURI = "https://quality.data.gov.tw/dq_download_json.php?nid=116285&md5_url=53a72b2dcfdd9ecae43afda4b86089be"; // using自动管理HttpClient生命周期 using (HttpClient client = new HttpClient()) { client.MaxResponseContentBufferSize = Int32.MaxValue; var response = await client.GetStringAsync(targetURI); var pharmacy = JsonConvert.DeserializeObject<List<Inserch>>(response); // using自动管理SqlConnection,无需手动关闭 using (SqlConnection connection = new SqlConnection(connstr)) { await connection.OpenAsync(); string sql = "Insert into pharmacy(ID,Name,Address,Phonenumber) values(@ID,@Name,@Address,@Phonenumber)"; // using自动管理SqlCommand using (SqlCommand cmd = new SqlCommand(sql, connection)) { // 提前定义参数,避免重复添加 cmd.Parameters.Add("@ID", SqlDbType.VarChar); // 需根据数据库实际列类型调整 cmd.Parameters.Add("@Name", SqlDbType.NVarChar); cmd.Parameters.Add("@Address", SqlDbType.NVarChar); cmd.Parameters.Add("@Phonenumber", SqlDbType.VarChar); foreach (var item in pharmacy) { // 循环内仅更新参数值 cmd.Parameters["@ID"].Value = item.ID; cmd.Parameters["@Name"].Value = item.Name; cmd.Parameters["@Address"].Value = item.Address; cmd.Parameters["@Phonenumber"].Value = item.Phonenumber; await cmd.ExecuteNonQueryAsync(); } } } return pharmacy; } }
额外建议
- 确保数据库参数类型与
Inserch类属性、数据库列类型一致,避免隐式转换问题。 - 数据量较大时,建议使用
SqlBulkCopy实现批量插入,提升效率。 - 添加日志记录,方便排查运行时错误。
内容的提问来源于stack exchange,提问作者鍾佩妤
相关产品推荐
相关产品推荐

