papieros Opublikowano 26 Września 2010 Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
Mion Opublikowano 26 Września 2010 Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
papieros Opublikowano 26 Września 2010 Autor Udostępnij Opublikowano 26 Września 2010 @Mion, dzięki ... prawie działa. Prawie bo MySQL nie zwraca błędu (czyli syntax OK) ale zapytanie zwraca pusty resultset ... a nie powinno Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Mion Opublikowano 26 Września 2010 Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
papieros Opublikowano 26 Września 2010 Autor Udostępnij Opublikowano 26 Września 2010 Bingo, właśnie wyczytałem, że REAL może nie działać (a taki typ zwraca funkcja), powalczę z DECIMAL w takim razie EDIT: Z decimalem też nie działa (poprzez castowanie CAST() ) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Mion Opublikowano 26 Września 2010 Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
papieros Opublikowano 26 Września 2010 Autor Udostępnij Opublikowano 26 Września 2010 Oczywiście, że sprawdzałem co zwraca funkcja (takim sposobem jak u Ciebie). Zwraca poprawną wartość. Problem chyba tkwi w typie zwracanej wartości - REAL albo REAL CASTOWANY do DECIMAL'A Dzięki, już poradziłem sobie inaczej (chyba nawet lepiej ) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Mion Opublikowano 26 Września 2010 Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
papieros Opublikowano 26 Września 2010 Autor Udostępnij Opublikowano 26 Września 2010 Cytat 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 Więcej opcji udostępniania...
Mion Opublikowano 26 Września 2010 Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
papieros Opublikowano 26 Września 2010 Autor Udostępnij Opublikowano 26 Września 2010 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 Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Zarchiwizowany
Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.