web-dev-qa-db-fra.com

Vues avec paramètres, est-ce possible?

Je travaille dans une application PHP et certaines requêtes "complexes" commencent à apparaître dans le code. En raison de la complexité, je ne peux pas utiliser d'ORM et la seule ressource dont je dispose est un SQL simple et PHP Fonctions natives MySQL que je n'aime pas.

Sans plus voici une des requêtes que je veux convertir en vue:

SELECT
  COUNT(*) AS 'rec',
  CONCAT(
      IF(agreement_list.ActiveFlag, '', 'Agreement is Inactive.'),
      IF(agreement_type.ActiveFlag, '', 'Agreement Type is Inactive.'),
      IF(distributor.ActiveFlag, '', 'License Distributor is InActive.'),
      IF(agreement_distributor.ActiveFlag, '', 'Agreement Distributor is InActive.'),
      IF(customer.ActiveFlag, '', 'Customer is Inactive.'),
      IF(cf_program_level.ActiveFlag, '', 'Program Level is Inactive.')
  ) AS errormessage,
  IF((agreement_list.ActiveFlag + agreement_type.ActiveFlag + distributor.ActiveFlag + agreement_distributor.ActiveFlag + customer.ActiveFlag + cf_program_level.ActiveFlag) < 6, 1, 0 ) AS error
FROM
  license
  JOIN agreement_list ON (agreement_list.AgreementTypeID = license.AgreementTypeID AND agreement_list.CustomerSiteID = license.CustomerSiteID AND agreement_list.Source = license.Source)
  JOIN customer ON (customer.id = license.CustomerSiteID AND license.source = customer.Source)
  JOIN distributor ON (distributor.DistributorID = license.DistributorID AND license.source = distributor.Source)
  JOIN distributor AS agreement_distributor ON (agreement_distributor.DistributorID = agreement_list.DistributorID AND agreement_list.source = agreement_distributor.Source)
  JOIN agreement_type ON (agreement_type.AgreementTypeID = license.AgreementTypeID AND license.source = agreement_type.Source)
  JOIN cf_program_level ON (cf_program_level.CFProgramLevelID = '{$CFProgramLevelID}' AND license.source = cf_program_level.Source)
WHERE
  license.AgreementTypeID = '{$AgreementTypeID}'
  AND license.CustomerSiteID = '{$CustomerSiteID}'
  AND license.Source = '{$Source}'

$CFProgramLevelID, $AgreementTypeID, $CustomerSiteID, $Source sont des paramètres provenant de PHP et c'est mon seul problème. Comment passer un paramètre à une vue si c'est possible?

J'utilise MySQL 5.6 pour le moment.

3
ReynierPM

Semble simple. Construisez le VIEW sans les 5 dernières lignes. Utilisez ensuite ces 5 lignes lorsque vous utilisez le VIEW comme s'il s'agissait d'un TABLE.

Si ces JOINs ne sont pas "plusieurs: un", vous obtiendrez une COUNT(*) gonflée.

2
Rick James

Mieux encore, vous pouvez transmettre des paramètres à vos vues de manière simple en créant une fonction pour obtenir vos valeurs à partir des variables de session.
Voir www.stackoverflow.com/questions/14511760 pour la technique. Ceci est une copie de ma fonction de création que vous pouvez suivre.

DELIMITER //

CREATE FUNCTION fn_getcase_id()    
RETURNS MEDIUMINT(11)
DETERMINISTIC NO SQL
BEGIN
# see stackoverflow.com/questions/14511760 and read ALL the info TWICE or MORE.  wh 04/13/2017
    RETURN @sv_case_id;
END//

DELIMITER ;

Vous devrez créer 4 FN similaires (un pour chaque variable).

2
Wilson Hauck

Ne peut faire. Du moins pas directement. Utilisez une procédure qui remplit une table temporaire et référencez la table dans votre code.

0
jfroebe

ne alternative fonctionnelle serait d'encapsuler la requête de vue dans une procédure, avec passage de paramètres. Il s'agit d'une solution simple pour améliorer le problème des VUES lentes avec plusieurs requêtes de jointures entre plusieurs tables.

DELIMITER ;;
CREATE PROCEDURE `SP_QUERY_VIEW_WITH_PARAMETERS`(IN p_having VARCHAR(300))
    COMMENT 'Executes the statement'
BEGIN
  SET @v_having = p_having;
  SET @v_sql=CONCAT('SELECT 
                    id    AS id_emp  ,
                    user  AS emp_name,
                    .
                    .
                    .
                    FROM table1
                    UNION ALL
                    SELECT 
                    idtifier_us    AS id_emp  ,
                    description    AS emp_name,
                    .
                    .
                    .
                    FROM table2');
SET @v_sql2 = CONCAT(@v_sql,@v_having);
  PREPARE stmt FROM @v_sql2;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END ;;
DELIMITER ;


CALL `SP_QUERY_VIEW_WITH_PARAMETERS`('having id_emp=63 and emp_name like ''VANDERLEI%'' and created_at between ''2019-05-01'' and ''2019-05-17''  ')