Witam,

Mam problem. Wszystko sprawdziłem 10 razy, wszystko pwoinno działać, a nie działa.

Mam funkcję:

  1. CREATE DEFINER=`root`@`localhost` FUNCTION `towar_desc`(`a_gdzie` MEDIUMINT, `a_kto` MEDIUMINT, `a_co` MEDIUMINT, `a_ile` MEDIUMINT, `a_T` MEDIUMINT) RETURNS mediumint(9)
  2. NO SQL
  3. begin
  4. declare ile_bylo int;
  5. declare deleted int;
  6. IF a_T IS NULL then
  7. SET deleted = 0;
  8.  
  9. usun: loop
  10.  
  11. SELECT m.ile, m.T INTO ile_bylo, a_T FROM miasto_towar AS m
  12. WHERE id >= towar_id(a_gdzie, a_kto, a_co, 0) AND id < towar_id(a_gdzie, a_kto, a_co+1, 0) LIMIT 1;
  13. IF ile_bylo IS NULL then
  14. leave usun;
  15. end IF;
  16. IF ile_bylo > a_ile then
  17. UPDATE miasto_towar SET ile=ile-a_ile WHERE id=towar_id(a_gdzie, a_kto, a_co, a_T);
  18. SET deleted = deleted + a_ile;
  19. leave usun;
  20. else
  21. DELETE FROM miasto_towar WHERE id=towar_id(a_gdzie, a_kto, a_co, a_T);
  22. SET deleted = deleted + ile_bylo;
  23. SET a_ile = a_ile - ile_bylo;
  24. IF a_ile > 0 then
  25. iterate usun;
  26. else
  27. -- miejsce "A", opis w tekście
  28. leave usun;
  29. end IF;
  30. end IF;
  31.  
  32. end loop usun;
  33. else
  34. -- nieistotne
  35. end IF;
  36. RETURN deleted;
  37. end



parametry wejściowe to:
a_gdzie - w jakim mieście
a_kto - u kogo
a_co - jaki towar
a_ile - ile towaru
a_T - parametr T towaru

chodzi o to, że jeżeli za a_T dam NULL, funkcja ma usuwać towary z parametrem T do czasu, aż usunie ich a_ile.

dla przykładowej tabeli:

  1. TABELA miasto_towar
  2. id, gdzie, kto, co, ile, T
  3. WARTOŚCI:
  4. 12001300100001,12,13,1,10,1
  5. 12001300100002,12,13,1,10,2
  6. 12001300100003,12,13,1,10,3
  7. 12001300100004,12,13,1,10,4


Czyli produkt co=1 w mieście 12 u usera 13 ma łącznie 40 sztuk (10 o T=1, 10 o T=2 itd.)

Moja funkcja zwraca ile towaru udało się usunąć.
powinna zwracać następujące wartości:

select towar_desc(12,13,1,5, NULL) -- wynik: 5
select towar_desc(12,13,1,15, NULL) -- wynik: 15
select towar_desc(12,13,1,35, NULL) -- wynik: 35

i tak jest w istocie.

jeżeli natomiast napisze

select towar_desc(12,13,1,100, NULL)

zwraca wartość 100, a powinna 40 (bo usunięto tylko 40 sztuk)



nie wiem czemu.


i teraz najciekawsze:

w miejscu w kodzie oznaczonym "A"
napisałem

return deleted;

wywołując (za każdym razem na nowo definiuję tabele miasto_towar)

select towar_desc(12,13,1,100, NULL)

otrzymałem 100 (powinno być 40).



następnie w miejscu "A" napisałem

return a_ile;

wywołując

select towar_desc(12,13,1,100, NULL)

otrzymałem 100 (powinno być 90).


następnie w miejscu "A" napisałem

return ile_bylo;

wywołując

select towar_desc(12,13,1,100, NULL)

otrzymałem 10 (powinno być 10, czyli się zgadza).


Czyli nie działa mi fragment

set deleted = deleted + ile_bylo;
set a_ile = a_ile - ile_bylo;

nie rozumiem dlaczego!


Proszę o pomoc.

nie wiem, czy kogoś to jeszcze obchodzi, ale znalazłem błąd smile.gif

otóż polecenie

  1. SELECT m.ile, m.T INTO ile_bylo, a_T FROM miasto_towar AS m
  2. WHERE id >= towar_id(a_gdzie, a_kto, a_co, 0) AND id < towar_id(a_gdzie, a_kto, a_co+1, 0) LIMIT 1;


działa tylko wtedy, jeżeli wynikiem nie jest NULL

tz. mam np. ile_bylo = 5
jeżeli wykonam to polecenie dla warunków, które jako rezultat dają zbiór pusty, to zamiast
ile_bylo = NULL
otrzymuję dalej
ile_bylo = 5 - po prostu wtedy sql nie modyfikuje zmiennej!!!!

Bez sensu sprawa...
piszę, bo może komuś się ta wiedza przyda happy.gif