【问题标题】:Inserting Scraped Results Into SQL Server将抓取的结果插入 SQL Server
【发布时间】:2014-09-21 22:55:08
【问题描述】:

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

这是我正在使用的代码:

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);
        }
    }
}

【问题讨论】:

  • 仔细查看异常,您应该有一个 InnerException 可以更好地告诉您调用中的问题。

标签: c# html sql-server


【解决方案1】:

这个

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

应该是

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

此外,当您使用using 打开连接时,您不需要显式关闭连接。

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

    opencon.Close();   // not needed 

【讨论】:

  • querySaveStaff.Parameters.Add("@AlbergoName", SqlDbType.NChar, 30).String nome = nodo.SelectSingleNode("./h3[1]/a[1]").InnerText; 是怎么回事
  • 哇,超快回复!!修复了它,但仍然出现错误,它说字符串或二进制数据可能被截断。问题可能出在代码的 Foreach 部分...感谢 Close() 提示,我不知道它可以省略!
【解决方案2】:

我认为 sql 异常,除了缺少右括号的明显语法错误(错字?)来自您声明一个名为 @AlbergoName 的参数但在 sql 文本中使用 @987654322改为@占位符

改为:

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

顺便说一句,你不需要在循环内部创建SqlCommand,只需在外部创建并更新它的参数值

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,无论变量名称的长度如何,您都会传递 30 个字符。我建议使用 NVARCHAR 作为参数类型并将大小设置为与列名称相同的大小......

【讨论】:

  • 我已经编辑了上面的代码(对不起,我尝试了各种解决方案并发布了一个混乱的代码),并按照您的建议进行了更正。我仍然收到截断数据的错误。感谢您的快速回复!
  • 好吧,现在的问题是传递给您的名称字段的数据长度。您将参数声明为 30 个字符,但数据表中字段的长度是多少?使用 NVARCHAR 参数并确保它不大于列
  • 别忘了,如果字段在SQL Server中定义为nvarchar,那么SQL Server报告的字段大小的长度是实际大小的两倍;所以,如果 SQL Server 说长度是 30,那么你只能在字段中插入 15 个字符。
  • @MetroSmurf 你确定吗?好像不像你说的那样
  • 谢谢!有用!对不起,我对 Sql 很陌生!谢谢大家的回复,真的!
猜你喜欢
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 2013-02-04
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
相关资源
最近更新 更多