Skocz do zawartości

MySQL i funkcje użytkownika


papieros

Rekomendowane odpowiedzi

zdefiniowałem sobie funkcję przez CREATE FUNCTION i mam pewien mały problem, otóż:

Zapytanie wygląda mniej więcej tak:

SELECT a,b, MOJA_FUNKCJA(c,d) FROM tablica1,tablica2 WHERE a>b AND MOJA_FUNKCJA(c,d)>10

I teraz, wg. mnie powtórzenie dwa razy MOJA_FUNKCJA jest niepotrzebne i prawdopodobnie silnik będzie ją liczył dwa razy (czy na pewno?).

Próbowałem rozwiązania typu SELECT ... MOJA_FUNKCJA(..) AS F FROM .... WHERE ... F>10 ale nie działa.

Walczył ktoś z tym, można to jakoś zoptymalizować?

Odnośnik do komentarza
Udostępnij na innych stronach

Spróbuj zastosować tak zwane zmienne w MySQL i przypisz im to co zwraca Twoja funkcja

https://dev.mysql.com/doc/refman/5.0/en/user-variables.html

Czy w Twoim wypadku zadziała to nie wiem, ale spróbuj.

SELECT a,b, @myfunkcaja :=MOJA_FUNKCJA(c,d) FROM tablica1,tablica2 WHERE a>b AND @myfunkcaja >10

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Może funkcja nie zwraca typu INT przez co nie działa zgodnie z oczekiwaniem.

--

Sprawdź, bez definiowania funkcji w klauzuli select czyli

SELECT a,b FROM tablica1,tablica2 WHERE a>b AND MOJA_FUNKCJA(c,d)>10

co wydaje się zasadne

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Sprawdzałeś tak jak podałem w edycji:

SELECT a,b FROM tablica1,tablica2 WHERE a>b AND MOJA_FUNKCJA(c,d)>10

---

Poza tym możesz sprawdzić jaką wartość zawiera zmienna zwracana przez Twoją funkcję wyświetlając ją

SELECT a,b, @myfunkcaja :=MOJA_FUNKCJA(c,d), @myfunkcaja FROM

jeśli jest to typ INEGR klauzula AND @myfunkcaja >10 powinna działać :)

-----------

Poza tym :)

Jeśli utworzymy funkcję składowaną zwracająca zakładany typ w tym testowym wypadku jest to INT

CREATE FUNCTION `TestowaInt` (wejscie INT) RETURNS INT
BEGIN
  declare myint int;
  SET myint = wejscie;
  RETURN myint; 
END $$
DELIMITER;

I wywołamy jak podałem:

SELECT n.`category_id`, n.`name` , @myfunkcaja :=TestowaInt(6)  FROM nested_category n WHERE n.`category_id` > @myfunkcaja;

lub

SELECT n.`category_id`, n.`name` FROM nested_category n WHERE n.`category_id` > TestowaInt(6);

Podane przeze mnie przykłady działają prawidłowo co zresztą sprawdzałem. Wiec IMHO Masz błąd w swojej logice zapytania.

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Reasumując Masz niezgodność typu zwracanego przez funkcję z porównywanym > 10 czyli INT .

@ już poradziłem sobie inaczej

To najważniejsze. Funkcje składowane są bardzo pomocne pod warunkiem, że są prawidłowo zaprojektowane ;) oraz jeśli użytkownik bazy danych ma uprawnienia do ich tworzenie, a takowe na hostingach współdzielonych raczej nie są .

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Masz niezgodność typu zwracanego przez funkcję z porównywanym > 10 czyli INT .

Próbowałem na różne sposoby >10, >10.0 , >"10.0", >"10" już nawet po rozwiązaniu problemu - tak z ciekawości. Nic nie działało ;)

A zapytanie rzeczywiście do najprostszych nie należało - iloczyn kartezjański dwu tablic, a właściwie tej samej tablicy x2 + dodatki z innych więc może gdzieś po drodze się rypnąłem ... ale raczej to problem mysql'a z typami (o czym przestrzegają w podanym przez Ciebie linku)

PS. A problem polegał na znalezieniu wszystkich najbliższych punktów (na płaszczyźnie) dla każdego punktu zapisanego w tablicy nie dalszych niż R za pomocą jednego select'a.

Odnośnik do komentarza
Udostępnij na innych stronach

Na chłopski rozum.. jeśli zdefiniujemy w ciele funkcji zmienną

declare myint int

której przypiszemy

SET myint = dane typu INT uzyskane w wyniku wewnętrznych zapytań nieważne jak skomplikowanych i ją zwrócimy

RETURN myint;

to funkcja musi działać zgodnie z oczekiwaniem. Chyba, że silnik MySQL w tej kwestii zawiera jakieś bugi które nie zostały wykryte :)

@tak z ciekawości.

Przypisałeś w ciele funkcji testową wartość typu INT i ja na "sztywno" zwracałeś...

;)

HTTP 200 usługi IT -> Dariusz Janicki | Realizacja serwisów www oraz oprogramowania w PHP / C# / Golang / Node.js / MySQL/ Laravel
Komory normobaryczne - normobaria.tech Wykonawca montażu i instalacji komory normobarii

Odnośnik do komentarza
Udostępnij na innych stronach

Nie bardzo rozumiem o co Ci chodzi

Funkcja zwracała wartość rzeczywistą i chyba tu był problem. Oczywiście można by spróbować pomnożyć ową wartość zwracaną przez 1eX (1*10 do potęgi X) gdzie X - potrzebna dokładność, tak aby funkcja zwracała INTEGER ale dałem sobie spokój z tym już, tym bardziej, że rozwiązanie, które znalazłem jest chyba bardziej optymalne niż to z zastosowaniem funkcji składowanych. Może kiedyś do tego wrócę - na dzień dzisiejszy moja diagnoza jest taka, że MySql ma problem z funkcjami składowanymi, które zwracają typy REAL, DECIMAL, DOUBLE lub podobne

Odnośnik do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę. Warunki użytkowania Polityka prywatności