2014-09-21 44 views
0

任何想法为什么我得到“System.Data.dll中发生类型'System.Data.SqlClient.SqlException'的未处理异常”,当我尝试将sccraping的结果插入SQL SERVER时?将损坏的结果插入到SQL Server中

这是我使用的代码:

public void scrape(string URL) 
{ 
    using (SqlConnection opencon = new SqlConnection("CONNECTION STRING")) 
    { 
     string saveStaff = "INSERT into Principale ((Name) VALUES (@Name)"; 
     opencon.Open(); 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL); 
     request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; 
     request.AllowAutoRedirect = false; 

     WebResponse response = request.GetResponse(); 
     StreamReader streamreader = new StreamReader(response.GetResponseStream()); 
     string html = streamreader.ReadToEnd(); 

     HtmlDocument page = new HtmlDocument(); 
     page.LoadHtml(html); 
     var document = page.DocumentNode.SelectNodes("//div[@class='b_Namesummary']"); 

     foreach (var nodo in document) 
     { 

      String nome = nodo.SelectSingleNode("./h3[1]/a[1]").InnerText; 
      SqlCommand querySaveStaff = new SqlCommand(saveStaff); 
      querySaveStaff.Connection = opencon; 
      querySaveStaff.Parameters.Add("@Name", SqlDbType.NChar, 30).Value = nome; 
      querySaveStaff.ExecuteNonQuery(); 
      Console.WriteLine(nome); 
     } 
    } 
} 
+0

仔细查看异常情况,您应该有一个InnerException,它可以更好地告诉您的调用出了什么问题。 – Steve 2014-09-21 14:36:50

回答

0

我认为SQL异常,除了明显的语法错误缺少右括号,(笔误?)来自于事实,你声明参数命名@AlbergoName但在SQL文本中使用@name占位符代替

更改为:

string saveStaff = "INSERT into Principale (Name) VALUES (@AlbergoName)"; 

顺便说一句,你不需要创建循环内的SqlCommand的,只是创建IT运utside并更新其参数值

SqlCommand querySaveStaff = new SqlCommand(saveStaff); 
querySaveStaff.Connection = opencon; 
querySaveStaff.Parameters.Add("@AlbergoName", SqlDbType.NVarChar, 30); 
foreach (var nodo in document) 
{ 
    string nome = nodo.SelectSingleNode("./h3[1]/a[1]").InnerText; 
    Console.WriteLine(nome); 

    querySaveStaff.Parameters["@AlbergoName"].Value = nome; 
    querySaveStaff.ExecuteNonQuery(); 
} 

另请注意,我已将您的参数类型更改为NVARCHAR而不是NCHAR。 NChar是一个固定长度的类型,所以如果你声明NChar 30,那么无论变量Nome的长度如何,你都会传递30个字符。我建议使用NVARCHAR作为参数类型,并将大小设置为与列名相同的大小....

+0

我编辑了上面的代码(对不起,我尝试了各种解决方法,并发布了一个混乱的代码)与您建议的更正。 我仍然收到截断数据的错误。 感谢您的快速回复! – Jack 2014-09-21 14:44:10

+0

那么,现在的问题是传递到您的名称字段的数据的长度。您声明参数为30个字符,但数据表中字段的长度是多少?使用NVARCHAR参数并确保它不大于列 – Steve 2014-09-21 14:45:32

+0

不要忘记,如果该字段在SQL Server中定义为“nvarchar”,那么字段大小的长度SQL Server报告是实际大小的两倍;所以,如果SQL Server表示长度为30,那么只能在该字段中插入15个字符。 – 2014-09-21 14:50:24

3

"INSERT into Principale (Name VALUES (@Name)"; 

应该

"INSERT into Principale (Name) VALUES (@Name)"; 

而且你并不需要显式地关闭连接时,您使用using打开连接。

当使用块超出范围时,连接将自动关闭。 (一个很好的理由来使用using超过Try, catch, finnaly

opencon.Close(); // not needed 
+0

'querySaveStaff.Parameters.Add(“@ AlbergoName”,SqlDbType.NChar,30).'和'String nome = nodo.SelectSingleNode(“./h3 [1]/a [1]”)。InnerText;' – bummi 2014-09-21 14:34:47

+0

哇,超快回复!修正了它,但仍然出现错误,它表示字符串或二进制数据可能被截断。问题可能出现在代码的Foreach部分中... 感谢Close()提示,我不知道它可以省略! – Jack 2014-09-21 14:36:52