Mysql function mit cursor funktnioniert nicht?

ich hab eine mysql function, die mir immer den wert null liefert, aber ich verstehe nicht wieso, da sie eigentlich einen decimal wert liefern sollte. hier der code:

DELIMITER $$

CREATE DEFINER=dapro23@localhost FUNCTION foreignavg() RETURNS decimal(10,3)
BEGIN
declare germancount decimal(1,0);
declare foreigncount decimal(1,0);
declare country Varchar(45);
declare avgc decimal(10,3);
declare nomorecountrys INT;
declare ga_cursor cursor for
select Country from Guestaddress Order by Country ASC;

declare exit handler for not found set nomorecountrys =1;

set nomorecountrys =0, germancount=0,foreigncount=0;
open ga_cursor;

while(nomorecountrys = 0) DO fetch ga_cursor into country;

if(country „Germany“) then set germancount=germancount+1;
else set foreigncount =foreigncount+1;
end if;

end while;
close ga_cursor;

set avgc=germancount/foreigncount;

return avgc;
END

Mit Stored Procedures habe ich leider noch nicht intensiv gearbeitet. Daher kann ich Dir nur sagen, was mir als potenzielle Probleme aufgefallen ist:

>> if(country „Germany“)

Der Vergleich sollte meines wissens mit „“ nicht „“ durchgeführt werden.
Zudem: Wenn Country „verschieden“ von „Germany“ sollte doch dann foreigncount hochgezählt werden.
Ich nehme mal an, richtig wäre:

if (country = ‚Germany‘) then set germancount=germancount+1; else set foreigncount=foreigncount+1;

Dein zweiter Fehler ist bei:
>> set avgc = germancount / foreigncount;

Dort sollte wahrscheinlich stehen:
set avgc = germancount / (germancount+foreigncount);

Möglicherweise ist auch genau das dein Problem. Wenn nämlich „foreigncount“ = 0 ist, gibt es eine Division durch 0 und das Ergebnis ist NULL.

Eine andere Fehler könnte sein (oder später werden), dass germancount und foreigncount beide als decimal ohne nachkommastelle definiert sind:
Bei der Division beider zahlen wird möglicherweise das Zwischenergebnis (Ergebnis der Division) in einem solchen Datentyp Decimal(1,0) gespeichert und die Nachkommastellen werden verworfen.

Nächstes Problem ist eben auch wieder dieser Datentyp. Decimal(1,0) bedeutet, dass ein einstelliger ganzzahliger Wert darin gespeichert werden kann. Der größte Wert wäre damit „9“. Ich kann mir vorstellen, dass MySQL bei einer weiteren Erhöhung der gespeicherten 9 den Wert als nächstes auf „NULL“ (=passiert bei Fehler bei Berechnungen) setzt. Eine Division oder andere Rechenoperaton die als einen Operand „NULL“ hat, wird dann auch NULL ergeben.
Ändere also mal Testweise den Datentyp von Decimal(1,0) auf Decimal(10,0), Decimal(20,7) oder Integer(10).

Schreib doch dann bitte mal, was geholfen hat…

LG
Stefan

Hey Edu,

sorry mit MySQL Funktionen kenne ich mich nicht so wirklich gut aus um deine Frage jetzt wirklich beantworten zu können. Tut mir leid

LG Frank

kann leider nicht helfen - bitte kollegen fragen!
alles gute
peter

ich hab jetzt ein paar sachen geändert. bekomme nun aber eine andere fehlermeldung: function ended without return.

hier der code:

DELIMITER $$

CREATE DEFINER=dapro23@localhost FUNCTION foreignavg() RETURNS decimal(10,3)
BEGIN
declare germancount decimal(10,0);
declare foreigncount decimal(10,0);
declare country Varchar(45);
declare avgc decimal(20,7);
declare nomorecountrys INT;
declare ga_cursor cursor for
select Country from Guestaddress Order by Country ASC;

declare exit handler for not found set nomorecountrys =1;

set nomorecountrys =0, germancount=0.0,foreigncount=0.0;
open ga_cursor;

while(nomorecountrys = 0) DO fetch ga_cursor into country;
– if (nomorecountrys=0 and country IS NOT NULL) then
if(country = „Germany“) then set germancount=germancount+1.0;
else set foreigncount =foreigncount+1.0;
end if;
– end if;
end while;
close ga_cursor;

set avgc=germancount/foreigncount;

return avgc;
END

die kommentierten zeilen hab ich aus dem script meines profs übernommen, bin mir aber nicht sicher ob diese notwendig sind.

LG edu

Hallo Edu,

ich hab jetzt ein paar sachen geändert. bekomme nun aber eine
andere fehlermeldung: function ended without return.

Den Fehler im SQL sehe ich spontan nicht. Die Meldung beklagt allerdings, dass die aufgerufene Funktion beendet wurde, ohne einen Rückgabewert zu liefern. Möglicherweise führt eine fehlerhafte Anfrage zum vorzeitigen Abbruch der Funktion…

Ob der Teil „declare exit handler for not found set nomorecountrys =1;“ was damit zu tun hat, weiß ich nicht.

Vorschlag: Fang mal mit der ganz einfachen „leeren“ Funktion an und füge schrittweise die Befehle von oben bis unten wieder ein. Also nimm dies hier als Grundlage und erweitere es Stück für Stück…

DELIMITER $$

CREATE DEFINER=dapro23@localhost FUNCTION foreignavg() RETURNS decimal(10,3)
BEGIN
declare avgc decimal(20,7);
set avgc = 0;
return avgc;
END

Irgendwann wird der Fehler wieder auftreten und dann weißt Du welche Zeile das Problem ist.

Stefan

sorry, da kann ich dir leider im moment auch nicht weiterhelfen.

cu
harald
*******************