J'ai un point de vue comme celui-ci :
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = 2;
Je voudrais le rendre plus générique, c'est-à-dire changer 2 en variable. J'ai essayé ceci :
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = @MyVariable;
Mais MySQL ne le permet pas.
J'ai trouvé une vilaine solution de contournement :
CREATE FUNCTION GetMyVariable() RETURNS INTEGER DETERMINISTIC NO SQL
BEGIN RETURN @MyVariable; END|
Et puis la vue est :
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = GetMyVariable();
Mais l'apparence est vraiment mauvaise, et l'utilisation est également mauvaise - je dois définir la @MyVariable avant chaque utilisation de la vue.
Existe-t-il une solution que je pourrais utiliser comme ça ?
SELECT Column FROM MyView(2) WHERE (...)
La situation concrète est la suivante : J'ai une table qui stocke les informations sur la demande refusée :
CREATE TABLE Denial
(
Id INTEGER UNSIGNED AUTO_INCREMENT,
PRIMARY KEY(Id),
DateTime DATETIME NOT NULL,
FeatureId MEDIUMINT UNSIGNED NOT NULL,
FOREIGN KEY (FeatureId)
REFERENCES Feature (Id)
ON UPDATE CASCADE ON DELETE RESTRICT,
UserHostId MEDIUMINT UNSIGNED NOT NULL,
FOREIGN KEY (UserHostId)
REFERENCES UserHost (Id)
ON UPDATE CASCADE ON DELETE RESTRICT,
Multiplicity MEDIUMINT UNSIGNED NOT NULL DEFAULT 1,
UNIQUE INDEX DenialIndex (FeatureId, DateTime, UserHostId)
) ENGINE = InnoDB;
Une multiplicité est un nombre de demandes identiques enregistrées dans la même seconde. Je veux afficher une liste des refus, mais parfois, lorsque la demande est refusée, elle réessaie plusieurs fois, juste pour être sûre. Donc, généralement, lorsque le même utilisateur se voit refuser 3 fois la même fonction en quelques secondes, il s'agit en fait d'un seul refus. Si nous avions une ressource de plus, pour répondre à cette demande, les deux prochains refus n'auraient pas lieu. Nous voulons donc regrouper les refus dans un rapport permettant à l'utilisateur de spécifier l'intervalle de temps dans lequel les refus doivent être regroupés. Par exemple, si nous avons des refus (pour l'utilisateur 1 sur la fonction 1) dans les timestamps : 1,2,24,26,27,45 et l'utilisateur veut regrouper les refus qui sont plus proches les uns des autres que 4 sec, il devrait obtenir quelque chose comme ceci : 1 (x2), 24 (x3), 45 (x1). Nous pouvons supposer que les espaces entre les vrais refus sont beaucoup plus grands qu'entre les duplications. J'ai résolu le problème de la manière suivante :
CREATE FUNCTION GetDenialMergingTime()
RETURNS INTEGER UNSIGNED
DETERMINISTIC NO SQL
BEGIN
IF ISNULL(@DenialMergingTime) THEN
RETURN 0;
ELSE
RETURN @DenialMergingTime;
END IF;
END|
CREATE VIEW MergedDenialsViewHelper AS
SELECT MIN(Second.DateTime) AS GroupTime,
First.FeatureId,
First.UserHostId,
SUM(Second.Multiplicity) AS MultiplicitySum
FROM Denial AS First
JOIN Denial AS Second
ON First.FeatureId = Second.FeatureId
AND First.UserHostId = Second.UserHostId
AND First.DateTime >= Second.DateTime
AND First.DateTime - Second.DateTime < GetDenialMergingTime()
GROUP BY First.DateTime, First.FeatureId, First.UserHostId, First.Licenses;
CREATE VIEW MergedDenials AS
SELECT GroupTime,
FeatureId,
UserHostId,
MAX(MultiplicitySum) AS MultiplicitySum
FROM MergedDenialsViewHelper
GROUP BY GroupTime, FeatureId, UserHostId;
Ensuite, pour montrer les refus des utilisateurs 1 et 2 sur les fonctions 3 et 4 fusionnées toutes les 5 secondes, tout ce que vous devez faire est :
SET @DenialMergingTime := 5;
SELECT GroupTime, FeatureId, UserHostId, MultiplicitySum FROM MergedDenials WHERE UserHostId IN (1, 2) AND FeatureId IN (3, 4);
J'utilise la vue car il est facile d'y filtrer les données et de les utiliser explicitement dans la grille jQuery, de les ordonner automatiquement, de limiter le nombre d'enregistrements et ainsi de suite.
Mais c'est juste une vilaine solution de contournement. Existe-t-il une façon correcte de procéder ?