【问题标题】:What am I doing wrong with this query?我对这个查询做错了什么?
【发布时间】:2009-07-15 17:20:49
【问题描述】:

我似乎无法找到为什么此函数不将记录插入数据库。 :( 我没有收到任何错误消息或任何错误消息,数据库中什么也没有。

编辑:这就是我的查询现在的样子 .. 仍然没有 ..

connection.Open();
XmlNodeList nodeItem = rssDoc.SelectNodes("/edno23/posts/post");

foreach (XmlNode xn in nodeItem)
{
    cmd.Parameters.Clear();
    msgText = xn["message"].InnerText;
    C = xn["user_from"].InnerText;
    avatar = xn["user_from_avatar"].InnerText;
    string   endhash =  GetMd5Sum(msgText.ToString());
    cmd.Parameters.Add("@endhash",endhash);
    cmd.CommandText  = "Select * FROM posts Where hash=@endhash";
    SqlCeDataReader reader = cmd.ExecuteReader();

    while (reader.Read())
    {
        string msgs = reader["hash"].ToString();

        if (msgs != endhash || msgs == null)
        {
            sql = "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(@username,@messige,@userpic,@thedate,@hash)";
            cmd.CommandText = sql;
            cmd.Parameters.Add("@username", C);
            cmd.Parameters.Add("@messige", msgText.ToString());
            cmd.Parameters.Add("@userpic", avatar.ToString());
            cmd.Parameters.Add("@thedate", dt);
            cmd.Parameters.Add("@hash", endhash);
            cmd.ExecuteNonQuery();// executes query
            adapter.Update(data);// saves the changes
        }
    }

    reader.Close();
}

connection.Close();

【问题讨论】:

  • 你验证你进入了while循环,也进入了if块吗?
  • 使用调试器单步调试代码,你会学得更快

标签: c# .net sql sql-server database


【解决方案1】:

nodeItem 里面真的有项目吗?如果没有,则不会执行 foreach 循环的内容。

适配器和数据的用途是什么?查询和更新似乎是通过其他命令和阅读器完成的。

“哈希”实际上包含什么?如果是散列,为什么要在 while 循环中散列散列的内容?如果不是,为什么要与查询 SELECT * FROM posts WHERE hash = @endhash 中的哈希进行比较?

不会在while循环结束前关闭连接使用于控制循环的阅读器无效吗?

【讨论】:

  • 我正在做哈希的事情因为我想比较内容是否 100% 唯一如果它不插入内容如果它与以前的内容相同跳到下一个:) 我已经移动连接关闭
  • @Aviatrix:我认为您错过了哈希问题的重点。 hash 列包含一个哈希,是吗?您专门查询具有包含在endhash 中的哈希的记录。然后,您对包含在该列中的值进行 hash,即 99.99% gauranteed 以生成完全不同的哈希值,并将其与原始查询值进行比较 - never 将匹配。
  • 我修复了这个问题.. 我想比较两个哈希值,但是我错误地对哈希值进行了哈希处理.. o.O 任何人.. 我仍然没有添加任何记录:(
【解决方案2】:

这里发生了很多事情......

您正在使用命令“cmd”通过数据读取器循环遍历记录,然后在 while 语句中使用相同的“cmd”命令来执行插入语句。您之前声明了另一个命令“cmdAdd”,但似乎没有在任何地方使用它;这是您打算用于插入语句的内容吗?

您还可以在遍历数据读取器的 while 循环内关闭数据连接。您只会读取一条记录,然后以这种方式关闭与数据库的连接;如果不满足插入条件,则不会向数据库写入任何内容。

编辑:

您确实应该在 xmlnodes 上打开和关闭与 foreach 之外的数据库的连接。如果您有 10 个节点要循环,则数据库连接将打开和关闭 10 次(嗯,连接池可能会阻止这种情况,但仍然......)

您还似乎无缘无故地将整个“帖子”表加载到数据集中。您没有更改数据集中的任何值,但您正在重复调用它的更新(在“save teh shanges”处)。如果 'posts' 表非常大,这将无缘无故地占用大量内存(在手持设备上,同样如此)。

【讨论】:

  • 我修复了再次查看查询的问题.. :)
  • 您只想在哈希不存在的情况下插入一条记录,对吗?如果是这样,您甚至不需要遍历数据读取器。相反,只需执行 "select count(*) as hashcount from posts where hash=@endhash" ;如果值为零,则插入记录。
  • @Aviatrix:您仍然在每次通过循环将 new 参数添加到命令对象的参数集合中,而不是重新使用已经存在的参数。
【解决方案3】:

是否从“Select * FROM posts Where hash=@endhash”返回任何内容?

如果不是,那么 while 循环中的任何内容都不重要......

【讨论】:

    【解决方案4】:

    为什么要在 while 循环关闭数据库连接?
    当您尝试使用未打开的数据库连接对象调用 cmd.ExecuteNonQuery() 时,您发布的代码应该引发异常。

    SqlCeCommand.ExecuteNonQuery() 方法返回受影响的行数。
    为什么不在调试器中检查它是否返回1,如下所示?

    int rowsAffectedCount = cmd.ExecuteNonQuery();
    

    希望对你有帮助:-)

    【讨论】:

      【解决方案5】:

      您遇到了一些未实现“使用”块的问题。我在下面的内部代码中添加了一些。连接和选择命令的块是我的一厢情愿。我希望您对数据适配器也这样做。

      using (var connection = new SqlCeConnection(connectionString))
      {
          connection.Open();
          var nodeItem = rssDoc.SelectNodes("/edno23/posts/post");
      
          foreach (XmlNode xn in nodeItem)
          {
              using (
                  var selectCommand =
                      new SqlCeCommand(
                          "Select * FROM posts Where hash=@endhash",
                          connection))
              {
                  var msgText = xn["message"].InnerText;
                  var c = xn["user_from"].InnerText;
                  var avatar = xn["user_from_avatar"].InnerText;
                  var endhash = GetMd5Sum(msgText);
                  selectCommand.Parameters.Add("@endhash", endhash);
                  selectCommand.CommandText =
                      "Select * FROM posts Where hash=@endhash";
                  using (var reader = selectCommand.ExecuteReader())
                  {
                      while (reader.Read())
                      {
                          var msgs = reader["hash"].ToString();
      
                          if (msgs == endhash && msgs != null)
                          {
                              continue;
                          }
      
                          const string COMMAND_TEXT =
                              "INSERT INTO posts([user],msg,avatar,[date],hash) VALUES(@username,@messige,@userpic,@thedate,@hash)";
                          using (
                              var insertCommand =
                                  new SqlCeCommand(
                                      COMMAND_TEXT, connection))
                          {
                              insertCommand.Parameters.Add("@username", c);
                              insertCommand.Parameters.Add(
                                  "@messige", msgText);
                              insertCommand.Parameters.Add(
                                  "@userpic", avatar);
                              insertCommand.Parameters.Add("@thedate", dt);
                              insertCommand.Parameters.Add(
                                  "@hash", endhash);
                              insertCommand.ExecuteNonQuery();
                                  // executes query
                          }
                          adapter.Update(data); // saves teh changes
                      }
      
                      reader.Close();
                  }
              }
          }
      
          connection.Close();
      }
      

      当然,通过额外的嵌套,部分应该被分解为单独的方法。

      【讨论】:

      • 感谢您制定解决方案,但我认为一直使用错误的 sql 命令 ;) 而不是 ExecuteReader() 读取我需要的所有内容 ExecuteScalar() 只返回 1 个结果,我不需要更多 :) 我只需要确保散列是/不存在 :) avi.pastebin.com/f5aca84f4
      【解决方案6】:

      我怀疑你的问题是你试图重用相同的 SqlCeCommand 实例。

      尝试在 while 循环中创建一个新的 SqlCeCommand。此外,您可以使用using 语句来关闭您的数据对象。


      既然您根本没有更改 DataSet,为什么还要打电话给 adapter.Update(data)?我怀疑你想打电话给adapter.Fill(data)Update 方法会将 DataSet 中的任何更改保存到数据库中。

      【讨论】:

        【解决方案7】:

        如何调试程序:http://www.drpaulcarter.com/cs/debug.php

        说真的,你能发布更多关于它在哪里工作的信息吗?如果您使用 SQL Server Express 而不是 SQL CE,它是否有效?如果是这样,您能否打开 SQL Profiler 并查看正在执行的 SQL 命令?

        【讨论】:

          猜你喜欢
          • 2017-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多