Il est une propriété fondamentale de NULL
que lorsque vous comparez à quoi que ce soit, y compris — NULL
— retourne false
, ce qui explique pourquoi ce que vous faites ne fonctionne pas.
Donc la première question à laquelle il faut répondre est la suivante: pourquoi voulez-vous qu'une ligne avec NULL
lastname
soit retournée quand elle entre lastname
de "smith"? Peut-être que vous voulez dire que le prénom ou le nom de famille doit correspondre à être retourné, auquel cas vous n'exécutez pas la bonne requête. La solution la plus naïve est:
SELECT firstname, lastname, ....
FROM profiles
WHERE IFNULL(firstName LIKE'%{firstname}%'
OR lastName LIKE '%{lastName}%'
Maintenant, cela fonctionnera pour plusieurs centaines et peut-être plusieurs milliers de lignes, mais ne sera pas l'échelle au-delà de cela pour plusieurs raisons:
OR
s sont généralement affligeant en termes de performance. Évitez-les si possible. Si vous regardez les applications de base de données écrites par des programmeurs expérimentés, vous ne trouverez probablement pas une seule condition OR
(excepté ceux qui font du prosélytisme sur les vertus de OR
en ayant écrit une application guestbook qui a 3 utilisateurs et 2 hits par mois) ;
- Faire
LIKE
avec un %
à l'avant signifiera qu'aucun index ne sera poursuivi.
Il existe plusieurs solutions pour (2). Probablement le plus simple dans MySQL est d'utiliser full text searching sur les tables MyISAM. Il ne trouvera pas de correspondance comme "Johannes" si vous tapez "han" mais cela suffit généralement.
Souvent, vous gérez les conditions OR
en utilisant UNION
ou (de préférence) UNION ALL
sur plusieurs requêtes. Par exemple:
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName LIKE'%{firstname}%'
AND lastName LIKE '%{lastName}%'
UNION ALL
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName LIKE'%{firstname}%'
AND lastname IS NULL
UNION ALL
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName IS NULL
AND lastName LIKE '%{lastName}%'
UNION ALL
SELECT firstname, lastname, ....
FROM profiles
WHERE firstName IS NULL
AND lastName IS NULL
est assez grosse et laide, mais UNION ALL
échelles très bien (en ignorant le %
au début des LIKE
critères). Il s'agit essentiellement de concaténer (dans ce cas) quatre requêtes. Un UNION
fera un DISTINCT
implicite sur les lignes de résultats mais nous savons qu'il n'y aura pas de chevauchement ici parce que nous varions en vérifiant NULL
.
Une autre possibilité est de ne pas traiter NULL
comme quelque chose que vous voulez rechercher. C'est une solution bien meilleure et plus intuitive (imho). Si quelqu'un tape un nom de famille "Smith", voulez-vous vraiment des lignes avec un nom de famille NULL
? Ou voulez-vous qu'ils apparaissent parce que vous pourriez avoir une correspondance sur le prénom? Si oui, vous voulez une requête légèrement différente. Par exemple:
SELECT firstname, lastname, ....
FROM profiles
WHERE id IN (
SELECT id
FROM profiles
WHERE firstName LIKE'%{firstname}%'
UNION ALL
SELECT id
FROM profiles
WHERE lastName LIKE '%{lastName}%'
)
Avez-vous envisagé d'utiliser LINQ-to-SQL? –
non je n'ai pas encore considéré linq à sql ... –