Jak radzić sobie z (może) wartościami null W PreparedStatement?
Twierdzenie jest
SELECT * FROM tableA WHERE x = ?
I parametr jest wstawiany przez Javę.sql.PreparedStatement "stmt"
stmt.setString(1, y); // y may be null
Jeśli y
jest null, instrukcja nie zwraca wierszy w każdym przypadku, ponieważ {[4] } jest zawsze false (powinno być x IS NULL
).
Jednym z rozwiązań byłoby
SELECT * FROM tableA WHERE x = ? OR (x IS NULL AND ? IS NULL)
Ale potem muszę ustawić ten sam parametr dwa razy. Czy jest lepsze rozwiązanie?
Dzięki!5 answers
Zawsze robiłam to tak, jak pokazałeś w swoim pytaniu. Ustawienie tego samego parametru dwa razy nie jest takim wielkim trudem, prawda?
SELECT * FROM tableA WHERE x = ? OR (x IS NULL AND ? IS NULL);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 13:34:25
Istnieje dość nieznany operator ANSI-SQL IS DISTINCT FROM
, który obsługuje wartości NULL. Można go używać w ten sposób:
SELECT * FROM tableA WHERE x NOT IS DISTINCT FROM ?
Więc trzeba ustawić tylko jeden parametr. Niestety nie jest to obsługiwane przez MS SQL Server (2008).
Innym rozwiązaniem może być, jeśli istnieje wartość, która jest i nie będzie nigdy używana ('XXX'):
SELECT * FROM tableA WHERE COALESCE(x, 'XXX') = COALESCE(?, 'XXX')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-28 08:57:17
Użyłbym tylko 2 różnych wyrażeń:
Wypowiedź 1:
SELECT * FROM tableA WHERE x is NULL
Wypowiedź 2:
SELECT * FROM tableA WHERE x = ?
Możesz sprawdzić swoją zmienną i zbudować odpowiednie polecenie w zależności od warunku. Myślę, że to sprawia, że kod jest znacznie jaśniejszy i łatwiejszy do zrozumienia.
EDIT Przy okazji, dlaczego nie skorzystać z procedur przechowywanych? Następnie możesz obsłużyć całą tę logikę NULL w SP i możesz uprościć rzeczy na wywołaniu front end.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 13:27:49
Jeśli używasz np. mysql to prawdopodobnie możesz zrobić coś w stylu:
select * from mytable where ifnull(mycolumn,'') = ?;
Then yo could do:
stmt.setString(1, foo == null ? "" : foo);
Musisz sprawdzić swój plan wyjaśnień, aby zobaczyć, czy poprawia to Twoje wyniki. Oznaczałoby to jednak, że pusty łańcuch jest równy null, więc nie jest przyznany, że pasuje do Twoich potrzeb.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 14:08:56
W Oracle 11g robię to w ten sposób, ponieważ x = null
technicznie ocenia się na UNKNOWN
:
WHERE (x IS NULL AND ? IS NULL)
OR NOT LNNVL(x = ?)
Wyrażenie przed OR
zajmuje się zrównaniem NULL Z NULL, następnie wyrażenie po zajmuje się wszystkimi innymi możliwościami. LNNVL
zmiany UNKNOWN
na TRUE
, TRUE
do FALSE
i FALSE
do TRUE
, co jest dokładnym przeciwieństwem tego, czego chcemy, stąd NOT
.
Przyjęte rozwiązanie nie działało dla mnie w Oracle w niektórych przypadkach, gdy było częścią większego wyrażenie, obejmujące NOT
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 20:02:59