Maison > Questions et réponses > le corps du texte
J'ai deux programmes qui semblent presque identiques. Une personne reçoit Location et Prix et effectue l'opération, l'autre personne reçoit Expérience et Prix. < /p>
Premier :
-- Returns: service providers in given location and price DELIMITER && CREATE PROCEDURE get_service_providers_location_price (IN id_location INT,IN price DOUBLE,IN limite INT, IN inicio INT) BEGIN SELECT user.idUser, user.name,user.lastActivity,user.active,serviceprovider.description,location.name AS location, location.cordsX, location.cordsY, file.image FROM user INNER JOIN location ON user.idLocation = location.idLocation INNER JOIN file ON user.idUser = file.idUser INNER JOIN serviceprovider ON user.idUser = serviceprovider.idSP INNER JOIN category_has_serviceprovider ON serviceprovider.idSP = category_has_serviceprovider.idServiceProvider WHERE user.type = 3 AND user.idLocation = id_location AND (category_has_serviceprovider.price <= price OR category_has_serviceprovider.price IS NULL) and serviceprovider.idSubscription != 1 ORDER BY CASE WHEN serviceprovider.idSubscription in (5,6,7) then 1 else 2 end, serviceprovider.endSub ASC LIMIT limite OFFSET inicio; END && DELIMITER ;
Deuxième :
-- Returns: service providers in given experience and price DELIMITER && CREATE PROCEDURE get_service_providers_experience_price (IN experience INT, IN price DOUBLE,IN limite INT, IN inicio INT) BEGIN SELECT user.idUser, user.name,user.lastActivity,user.active,serviceprovider.description,location.name AS location, location.cordsX, location.cordsY, file.image FROM user INNER JOIN location ON user.idLocation = location.idLocation INNER JOIN file ON user.idUser = file.idUser INNER JOIN serviceprovider ON user.idUser = serviceprovider.idSP INNER JOIN category_has_serviceprovider ON serviceprovider.idSP = category_has_serviceprovider.idServiceProvider WHERE user.type = 3 AND (category_has_serviceprovider.price <= price OR category_has_serviceprovider.price IS NULL) AND category_has_serviceprovider.experience >= experience and serviceprovider.idSubscription != 1 ORDER BY CASE WHEN serviceprovider.idSubscription in (5,6,7) then 1 else 2 end, serviceprovider.endSub ASC LIMIT limite OFFSET inicio; END && DELIMITER ;
Comme vous pouvez le constater, seule la clause WHERE a changé. Dans MySQL, est-il possible de regrouper ces deux procédures en une seule ? Parce que j'ai environ 5 programmes qui se ressemblent mais ça change juste Clause WHERE, je trouve ennuyeux d'effectuer un processus séparé pour chaque cas.
P粉3156805652024-01-30 00:22:32
Vous pouvez utiliser IFNULL. Passez experience
或 id_location
值并使用 NULL
comme autre valeur.
C'est également une bonne pratique d'avoir un schéma de dénomination (ici in_
-préfixe) pour les paramètres afin que les paramètres soient différents des noms de colonnes.
DELIMITER && CREATE PROCEDURE get_service_providers_experience_price ( in_experience INT, in_id_location INT, in_price DOUBLE, in_limite INT, in_inicio INT ) BEGIN SELECT user.idUser, user.name, user.lastActivity, user.active, serviceprovider.description, location.name AS location, location.cordsX, location.cordsY, file.image FROM user INNER JOIN location ON user.idLocation = location.idLocation INNER JOIN file ON user.idUser = file.idUser INNER JOIN serviceprovider ON user.idUser = serviceprovider.idSP INNER JOIN category_has_serviceprovider ON serviceprovider.idSP = category_has_serviceprovider.idServiceProvider WHERE user.type = 3 AND (category_has_serviceprovider.price <= in_price OR category_has_serviceprovider.price IS NULL) AND category_has_serviceprovider.experience >= IFNULL(in_experience, category_has_serviceprovider.experience) AND user.idLocation = IFNULL(id_location, user.idLocation) AND serviceprovider.idSubscription != 1 ORDER BY CASE WHEN serviceprovider.idSubscription in (5,6,7) then 1 else 2 end, serviceprovider.endSub ASC LIMIT in_limite OFFSET in_inicio; END && DELIMITER ;
P粉9519143812024-01-30 00:22:16
Par exemple, vous pouvez utiliser ceci :
CREATE PROCEDURE get_service_providers_price (IN experience INT,IN id_location INT,IN price DOUBLE,IN limite INT, IN inicio INT) BEGIN SELECT user.idUser, user.name,user.lastActivity,user.active,serviceprovider.description,location.name AS location, location.cordsX, location.cordsY, file.image FROM user INNER JOIN location ON user.idLocation = location.idLocation INNER JOIN file ON user.idUser = file.idUser INNER JOIN serviceprovider ON user.idUser = serviceprovider.idSP INNER JOIN category_has_serviceprovider ON serviceprovider.idSP = category_has_serviceprovider.idServiceProvider WHERE user.type = 3 AND (category_has_serviceprovider.price <= price OR category_has_serviceprovider.price IS NULL) and serviceprovider.idSubscription != 1 AND CASE WHEN experience IS NOT NULL THEN category_has_serviceprovider.experience >= experience ELSE user.idLocation = id_location END ORDER BY CASE WHEN serviceprovider.idSubscription in (5,6,7) then 1 else 2 end, serviceprovider.endSub ASC LIMIT limite OFFSET inicio;
Si prévu IN 经验 INT
设置为某个值,则应用它的条件。如果您为此参数提供 NULL,则应用 IN id_location INT
conditions.
REMARQUE - Votre SP dispose désormais de 5 paramètres au lieu de 4.
PS. Votre SP contient une seule instruction SQL – BEGIN-END et DELIMITER ne sont donc pas nécessaires.PPS. En utilisant une approche similaire, vous pouvez créer un SP qui applique l’une des conditions, les deux ou aucune des deux. Par exemple, cela pourrait être :
AND CASE WHEN experience IS NOT NULL AND id_location IS NOT NULL -- apply both parameters filtering THEN category_has_serviceprovider.experience >= experience AND user.idLocation = id_location WHEN experience IS NOT NULL -- apply filtering by experience only THEN category_has_serviceprovider.experience >= experience WHEN id_location IS NOT NULL -- apply filtering by location only THEN user.idLocation = id_location ELSE 1 -- not filter, return all rows END
Parité de pouvoir d'achat. Si vous souhaitez avoir 2 fonctions distinctes mais avoir une copie du code (par exemple, ces noms de fonctions sont déjà utilisés dans un tas de code), alors vous pouvez faire ceci :
CREATE PROCEDURE get_service_providers_location_price (IN id_location INT,IN price DOUBLE,IN limite INT, IN inicio INT) CALL get_service_providers_price (NULL, id_location, price, limite, inicio); CREATE PROCEDURE get_service_providers_experience_price (IN experience INT, IN price DOUBLE,IN limite INT, IN inicio INT) CALL get_service_providers_price (experience, NULL, price, limite, inicio);