webForumDet fria alternativet

Unable to save result set in...

10 svar · 549 visningar · startad av lillebror

lillebrorMedlem sedan apr. 20041 597 inlägg
#1

Hej,

Idag fick jag ett mail där en användare berättade om ett MySQL-felmeddelande som förekommit på en sida som jag driver.

Felmeddelandet:

Warning: mysql_query() [function.mysql-query]: Unable to save result set in xxx/threadreply.php on line xxx
Subquery returns more than 1 row

Jag har själv inte sett det här felmeddelandet tidigare. Det dök upp som en blixt från klarblå himmel för mig. Jag förstår vad som står men jag har ännu inte påbörjat felsökning av felet. Tänkte kolla här om det är någon som kan "hinta" mig om varför det här dök upp?

MickeA.comMedlem sedan feb. 20034 441 inlägg
#2

Precis som det står så returnerar en subfråga mer än ett resultat. T.ex. om du har en fråga liknande den här:

SELECT a.user_id,
(SELECT name FROM tabell where id = a.user_id) AS namn
FROM en_annan_tabell

Felet uppstår när subfrågan, den mellan ( och ) ger te.x. två träffar. Enklaste lösningen är att ange LIMIT 1 så fixar det sig.

Alltså:

SELECT a.user_id,
(SELECT name FROM tabell where id = a.user_id LIMIT 1) AS namn
FROM en_annan_tabell
lillebrorMedlem sedan apr. 20041 597 inlägg
#3

Nu har jag kollat upp vad hänvisningen i felmeddelandet pekar på. Rad 112 är det som verkar utlösa felet. Här är koden:

	$RSobj_notify = mysql_query("SELECT COUNT(t1.threadreplyID) AS replynumber FROM tblforumthreadreply AS t1 WHERE t1.threadID = ".$threaddata['threadID']." AND t1.posted > (SELECT t2.date_time FROM tblforumthreadreplynotifier AS t2 WHERE t2.threadID = ".$threaddata['threadID']." AND memberID <> ".$_SESSION["uid"].")") or die (mysql_error());
	$notify = mysql_fetch_array($RSobj_notify);

Användarna säger att det här dyker upp sporadiskt? Är det något som man på direkten kan se är fel i koden utan att förstå mer ingående vad den gör?

Peter SMedlem sedan dec. 20025 483 inlägg
#4

Som Micke säger så är problemet att

SELECT t2.date_time FROM tblforumthreadreplynotifier AS t2 WHERE t2.threadID = ".$threaddata['threadID']." AND memberID <> ".$_SESSION["uid"]."

...returnerar fler än en rad.

För att åtgärda det föreslår jag att du använder MAX(t2.date_time) i stället.

MickeA.comMedlem sedan feb. 20034 441 inlägg
#5

Testa det här:

SELECT COUNT(t1.threadreplyID) AS replynumber 
FROM tblforumthreadreply AS t1 
WHERE t1.threadID = <threadID>
AND t1.posted > 
	(SELECT t2.date_time 
	FROM tblforumthreadreplynotifier AS t2 
	WHERE t2.threadID = <threadID>
	AND memberID <> <uid>
	LIMIT 1
	)

Subfrågan får alltså _aldrig_ ge mer än en post som resultat, vilket förhindras men LIMIT 1 som jag lade till ovan.

lillebrorMedlem sedan apr. 20041 597 inlägg
#6

Tack för snabb respons! Jag ska testa och se vad kodförändringen får för effekt.

Den här funktionen som koden ovan hänger ihop med ser till att medlemmar blir informerade om nya inlägg i en viss tråd om det är så att de valt att prenumera på den. Tabellstrukturen tblforumthreadreplynotifier ser ut som enligt bilden nedan. Primärnyckeln för tabellen är memberID och threadID. Försöker förstår varför det här felet har uppstått nu och inte förekommit tidigare.

*En stund senare*

Nu tror jag att jag har hittat boven i dramat. Det finns två personer i tabellen ovan som båda har valt att prenumera på information om när nytt inlägg postas i aktuell tråd. Därav så returneras två svar när sub-queryn ställs. Det här var absolut inget jag tänkte kunde inträffa när jag skrev koden för länge sen.

Det är just tråden med threadID 1379 som du uttryckt att de har haft problem med och båda dessa medlemmar har prenumererat på tråden i fråga.

Vad tror ni? Verkar det rimligt? Nu försöker jag förstår om LIMIT 1 kan få någon annan konstigt effekt för de som har valt att prenumerera på den här informationen.

tblforumthreadreplynotifier.pngtblforumthreadreplynotifier_result.png
MickeA.comMedlem sedan feb. 20034 441 inlägg
#7

Det känns som om du sparar onödigt mycket information och använder den på fel sätt, det blir snarare rörigt.

Tabellen som t.ex. heter "subscribers", där behöver du bara spara user, read_datetime, thread.

När ett nytt inlägg postas kör du en INNER JOIN mellan subscribers och users, där du hämtar alla epostadresser från users, där thread matchar tråden och där read_datetime är tidigare än nu.

Du behöver nog förresten en flagga där, som sätts till "true" när användare faktiskt besöker tråden, för att säkerställa att man bara får en påminnelse och inte en för varje nytt svar, fram tills en nästa besök.

lillebrorMedlem sedan apr. 20041 597 inlägg
#8

Den här koden skrev jag för 4 år sedan då jag höll på att lära mig programering. Av den anledningen är koden inte helt optimerad i alla avseenden. Nu har jag tagti fram migreringsscript för en övergång till vBulletin. Men jag är med på vad du säger om den aktuella koden.

MickeA.comMedlem sedan feb. 20034 441 inlägg
#9

Spelar ingen roll om koden är gjord igår eller för 10 år sen, men ville bara påpeka det. Du har ju ett problem som vi försöker lösa.

Om du ändå ska migrera så kanske du inte behöver göra något åt det.
Har du provat att lägga in LIMIT 1 i subfrågan?

nitro2k01Medlem sedan aug. 20039 342 inlägg
#10

MickeA: Så här tänker jag kring din kod. Som det är nu är det inte definierat vilken rad som hämtas ut, om det finns flera. Alltså borde man lägga till något i stil med ORDER BY t2.date_time DESC för att få ut det senaste datumet, om det nu är det man vill. Men då kan dock lika gärna använda MAX(t2.date_time) och få:

SELECT COUNT(t1.threadreplyID) AS replynumber 
FROM tblforumthreadreply AS t1 
WHERE t1.threadID = <threadID>
AND t1.posted > 
	(SELECT MAX(t2.date_time) 
	FROM tblforumthreadreplynotifier AS t2 
	WHERE t2.threadID = <threadID>
	AND memberID <> <uid>
	)
MickeA.comMedlem sedan feb. 20034 441 inlägg
#11

Jo, visst kan man göra så istället, är förmodligen bättre att använda max.

132 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)