【问题标题】:Why you should not use mysql_fetch_assoc more than 1 time?为什么你不应该使用 mysql_fetch_assoc 超过 1 次?
【发布时间】:2011-04-21 20:54:51
【问题描述】:

有人说你不应该多次使用mysql_fetch_assoc,这是为什么呢?

例如:我想显示两张表,一张是付费会员的用户,另一张是没有付费会员的用户,所以我不是查询数据库 2 次,而是查询一次,然后用两种类型的用户获取 $result 变量我运行循环 mysql_fetch_assoc 并查看是否 list['membership'] = 'paid' 然后回显 ...

我第二次循环循环mysql_fetch_assoc 看看是否list['membership'] = 'free' 然后回显...

考虑到注册和未注册的用户数量大致相同,什么会占用更少的资源。

【问题讨论】:

    标签: php mysql sql request


    【解决方案1】:

    将您的查询结果集想象成一根香肠,将 mysql_fetch_assoc() 想象成一把切下一根香肠的刀。每次你取一排,另一条香肠被切掉,它总是一条新的香肠。你不能去切掉之前切过的一块,因为它已经被吃掉了。

    【讨论】:

      【解决方案2】:

      Typer85 (link) 引用:

      请注意,您传递给此函数的资源结果可以被认为是通过引用传递的,因为资源只是指向内存位置的指针。

      因此,在将指针重置回起始位置之前,您不能在同一脚本中循环两次资源结果。

      例如:

      <?php
      
      // Assume We Already Queried Our Database.
      
      // Loop Through Result Set.
      
      while( $queryContent = mysql_fetch_row( $queryResult ) {
      
          // Display.
      
          echo $queryContent[ 0 ];
      }
      
      // We looped through the resource result already so the
      // the pointer is no longer pointing at any rows.
      
      // If we decide to loop through the same resource result
      // again, the function will always return false because it
      // will assume there are no more rows.
      
      // So the following code, if executed after the previous code
      // segment will not work.
      
      while( $queryContent = mysql_fetch_row( $queryResult ) {
      
          // Display.
      
          echo $queryContent[ 0 ];
      }
      
      // Because $queryContent is now equal to FALSE, the loop
      // will not be entered.
      
      ?>
      

      解决这个问题的唯一方法是重置指针,使其在第二个代码段之前再次指向第一行,所以现在完整的代码如下所示:

      <?php
      
      // Assume We Already Queried Our Database.
      
      // Loop Through Result Set.
      
      while( $queryContent = mysql_fetch_row( $queryResult ) {
      
          // Display.
      
          echo $queryContent[ 0 ];
      }
      
      // Reset Our Pointer.
      
      mysql_data_seek( $queryResult );
      
      // Loop Again.
      
      while( $queryContent = mysql_fetch_row( $queryResult ) {
      
          // Display.
      
          echo $queryContent[ 0 ];
      }
      
      ?>
      

      当然,您必须进行额外检查以确保结果中的行数不是0,否则mysql_data_seek 本身将返回false,并引发错误。

      另外请注意,这适用于所有获取结果集的函数,包括mysql_fetch_rowmysql_fetch_assosmysql_fetch_array

      【讨论】:

      • typer85 的示例似乎没有 mysql_data_seek 所需的参数 2
      • 感谢 Ina,她为我指明了正确的方向:mysql_data_seek($results,0) 需要这个位置。此外,a ) 在上面的代码中遗漏了
      【解决方案3】:

      当有人说您不能两次调用mysql_fetch_assoc() 时,他们的意思是针对同一个资源。您传递给mysql_fetch_assoc() 的资源结果是通过引用完成的。您需要重置指针的位置,然后才能再次使用 mysql_fetch_assoc()

      编辑:为此,请尝试使用mysql_data_seek()

      【讨论】:

      • 该函数的参数 2 是什么?
      • @ina 如果您的意思是mysql_data_seek(),它就是要查找的行号。我在线编辑了 PHP 手册的链接。
      • 由于某种原因将其设置为 0 会产生此错误:Offset 0 is invalid for MySQL result index 8 (or the query data is unbuffered
      【解决方案4】:

      看来您想要做的是将查询结果视为数组(字段)的数组(行)。但这并不是 mysql 库所提供的。实际上,我经常做的是将行复制到数组数组中(只需在 mysql_fetch 上循环直到为空),然后使用 PHP 为此目的提供的数组函数对自己的行集执行我想要的操作。这也最大限度地减少了表被锁定的时间。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-22
        • 1970-01-01
        • 1970-01-01
        • 2016-12-20
        • 2020-12-25
        • 2023-03-15
        相关资源
        最近更新 更多