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.
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.
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).
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.
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'' ')