recherche

Maison  >  Questions et réponses  >  le corps du texte

Comment regrouper 2 procédures en 1 dans MySQL ?

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粉998920744P粉998920744308 Il y a quelques jours398

répondre à tous(2)je répondrai

  • P粉315680565

    P粉3156805652024-01-30 00:22:32

    Vous pouvez utiliser IFNULL. Passez experienceid_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 ;

    répondre
    0
  • P粉951914381

    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 INTconditions.

    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);
    

    répondre
    0
  • Annulerrépondre