
![]() |
nutballs
whats with all the quirks I am finding? Obviously the
ASPmethodology and thePHPmethodology are less than compatible...stripped down to the junk that does it. should only update 5 rows, but oh no, its gotta update like 30 (actually its random). And its all because of the sleep(60). I assume the connection is resetting, but I don't get why it wouldn't just blow up? Why does it just go ahead and start processing more rows in the database?!?! public function gettargets() { $sql = "select Phrase,PhraseID from phrases limit 5"; $rs = mysql_query($sql,$GLOBALS['database']->conn); while ($row = mysql_fetch_assoc($rs)) { $sql = "update phrases set PhraseDate='".date('Y-m-d H:i:s')."' where PhraseID=".$row['PhraseID']; mysql_query($sql,$GLOBALS['database']->conn); sleep(60); } } perkiset
Dude I don't understand what you're trying to accomplish... you've put a re-query inside of a "while you're getting rows" loop... this code is guaranteed to fubar you nasty.
If what you are trying to do is re-query for 5 more every 60 seconds, then your loop should look more like: while (my master work statement is true) { mysql_query(for the 5 rows) while(mysql_fetch_object/assoc/row) { do code do code } sleep 60 seconds } or something like that... gotta run for the night, more tomorrow. In case you're confused, you only do the query once... you fetch until it comes back false, then you know you've exhausted the set returned by the query. /p <edit> Looking a second time it's clear... you're using the same database connection that should be returning rows to do the update. You'll need two database connections to do this, or the way I do it is collect my 5 rows into an array, then do my 5 updates - that's lighter and faster. You can't use a database connection to do two things at once... if you're mid-query and returning rows, you can't execute an update with it, it'll fish your dataset cursor. </edit> DangerMouse
This is quite interesting - thats something that I would have attempted myself. The only reason I can see for it not working, is that you're updating the same data that could be stored in your result set, which I guess could lead to problems - although I'm not sure this explains the random results.
I'm suprised the DB connection can't be reused, as ultimately the query has taken place and you're just looping a resultset resource which I'd have thought was already dragged into memory within the while statement. DM perkiset
The query function returns a handle to a MySQL result set, aka a cursor. As you fetch, you are literally requesting another row from that result set. This makes sense because if you have a result set of 10MM rows you would not want to wait for the result set to all DL before you could start processing. This behavior is the same as Oracle's.
If you retask <your connection> to the db, you are releasing the result set and all that would be left is a cached random mess of the original query. If you choose to update while connected, then the best way is multiple DB connections - otherwise, as I mentioned and if you know your result set is going to be small enough, the lightest way to go is to grab all rows into an array and then act on them. (It's all much clearer when I am awake ![]() nutballs
thats what I figured, and i also had worked out that you would probably say that... so...
$database = new database(); $sql = "select * from phrases limit 5"; $rs = mysql_query($sql,$database->conn); $phrasearray = array(); while ($row = mysql_fetch_assoc($rs)) { echo $row['Phrase'].'<br>'; $phrasearray[] = array('Phrase' => $row['Phrase'],'PhraseID' => $row['PhraseID']); } unset($row); //just in case there is some wierd latency. echo '----------<br>'; //just a separator. foreach ($phrasearray as $row) { echo $row['Phrase'].'<br>'; $sql = "update phrases set PhraseScrapeDate='".date('Y-m-d H:i:s')."' where PhraseID=".$row['PhraseID']; mysql_query($sql,$database->conn); sleep(30); } it seeems to be the sleep(30). obviously this is overly simplified, and you can guess what I am actually doing, but this oversimplification has the same problem. So this is the barebones example of what is going on. This new version dumps the results into an array, then does the processing. I understand what the issue is when I run a loop inside a loop, processing records from a record set, while it is "open", updating those records. It causes the original query to become invalid, when the next fetch is run, so it rebuilds it, and gets another 5 rows. The reason its random is because the script is timing out, and sometimes the queries run fast, others it runs slow, resulting in different numbers of records being processed. DUMB But i understand. ASPwas sheltering me from this via ADO. I could open a recordset and just walk around in it, willy nilly, making changes to it while doing so. Each record would commit the changes once i did a .update, but I would still have the same records in the recordset, regardless of the changes I make.In php/mysql, you apparently don't actually grab a whole recordset. you only grab the record for which your current cursor is located. So when you do a mysql_fetch_assoc, it increments the cursor counter by 1, and reruns the query from scratch, which means that if you have changed any of the criteria of the records from the prior result set which causes them to no longer be included in the result, you no longer get that record, and as such, you get a brand new one in this limit 5 scenario.So you mean to tell me mysql_fetch_assoc runs the query 5 times against the database when I do select * from table limit 5 while ($row = mysql_fetch_assoc($rs)) { echo 'wtf<br>'; } I get it, makes sense. dumb, but makes sense. So then answer me this sports fans... Why the hell does it do it still when I have moved on, using a single loop to dump it all into an array. The new example, does just this. should process 5, but it instead processes about 15 give or take. perkiset
Some quickies:
As an efficiency measure, you could do your loop as tightly as this: $set = mysql_query("select phrase, phraseid from phrases limit 5"); while ($phrases[] = mysql_fetch_array($set)); and the phrases array will have name=>value for each of the 5 rows. quote So you mean to tell me mysql_fetch_assoc runs the query 5 times against the database when I do select * from table limit 5 while ($row = mysql_fetch_assoc($rs)) echo 'wtf<br>'; I get it, makes sense. dumb, but makes sense. Doesn't run the query 5 times... just like Oracle, there is a temp set created for you (it's actually a temp table of pointers to records, but it is under the hood) and as you move the cursor you retrieve another record based on the pointer... so the query is done once and the cursor is bound to your connection to MySQL... when you die, the cursor becomes invalid and the set goes away. It's actually wicked fast. quote So then answer me this sports fans... Why the hell does it do it still when I have moved on, using a single loop to dump it all into an array. The new example, does just this. should process 5, but it instead processes about 15 give or take. If you are receiving more than 5 rows from a query where you explicitly state you want 5 then I am clueless, unless you're getting the entire table and there's some way to inhibit/unconfigure the LIMIT directive in MySQL which would be fantastically stupid. Where are you getting the "15ish?" perkiset
NBs - new posts up, as we discussed in
PHPrepository andPHPdiscussions.nutballs
or maybe not... LOL
still doing it!?!?!? dammit im gonna test more. <>per our offline conversation. the problem seems to be the connection to the database timing out, but PHPcontinuing along its merry way. What must be happening is thatphp, after 30 seconds, tries to do the next record, but Mysql is like "WTF are you talking about?"PHPmust respond, "this recordset: select * from table limit 5" and mysql returns that queryset, which of course is now an updated recordset. Thats why i was getting an increase in processed records.this is purely a "i used to be an ASPguy so i get my head stuck in the stairway railing" kind of thing.again. move along, nothing to see here. other than how not to do something. The solution is to open and close the connection each pass. Close before the sleep, and open when you loop again.> |

Thread Categories

![]() |
![]() |
Best of The Cache Home |
![]() |
![]() |
Search The Cache |
- Ajax
- Apache & mod_rewrite
- BlackHat SEO & Web Stuff
- C/++/#, Pascal etc.
- Database Stuff
- General & Non-Technical Discussion
- General programming, learning to code
- Javascript Discussions & Code
- Linux Related
- Mac, iPhone & OS-X Stuff
- Miscellaneous
- MS Windows Related
- PERL & Python Related
- PHP: Questions & Discussion
- PHP: Techniques, Classes & Examples
- Regular Expressions
- Uncategorized Threads