Mysql - 触发器不会更新我的数据库

时间:2014-04-02 15:05:35

标签: mysql triggers wamp wampserver

这是我的触发器:

--
-- Déclencheurs `reservation`
--
DROP TRIGGER IF EXISTS `UpdateFactureOnInsert`;
DELIMITER //
CREATE TRIGGER `UpdateFactureOnInsert` AFTER INSERT ON `reservation`
 FOR EACH ROW BEGIN
    DECLARE quota, montant, tarif INT;
    DECLARE nombreHeure INT DEFAULT (SELECT COUNT(heure.numero) FROM heure WHERE     heure.code = NEW.code);
    DECLARE mois INT DEFAULT (SELECT heure.mois FROM heure WHERE heure.code = NEW.code     LIMIT 1);
    DECLARE annee INT DEFAULT (SELECT heure.annee FROM heure WHERE heure.code = NEW.code     LIMIT 1);
    DECLARE identifiant INT DEFAULT (SELECT facture.identifiant FROM facture WHERE     facture.association = NEW.association
        AND facture.mois = mois
        AND facture.annee = annee LIMIT 1);  

    IF (identifiant = null) THEN
        SET identifiant = ((SELECT MAX(facture.identifiant) FROM facture) +1);
        INSERT INTO facture (facture.association, facture.annee, facture.mois,     facture.identifiant, facture.quota, facture.montant)
            VALUES (NEW.association, annee, mois, identifiant, 20, 0);
    END IF;

    SET quota = (SELECT facture.quota FROM facture WHERE facture.identifiant =     identifiant 
        AND facture.association = NEW.association
        AND facture.mois = mois
        AND facture.annee = annee);
    SET montant = (SELECT facture.montant FROM facture WHERE facture.identifiant = identifiant 
        AND facture.association = NEW.association
        AND facture.mois = mois
        AND facture.annee = annee);

    IF (nombreHeure >= quota) THEN
        SET quota = quota - nombreHeure;
    ELSE
        SET tarif = (SELECT salle.tarif FROM salle WHERE salle.numero = NEW.numero);
        SET montant = montant + (nombreHeure - quota) * tarif;
        SET quota = 0;
    END IF;

    UPDATE facture SET facture.quota = quota, facture.montant = montant WHERE     facture.association = NEW.association 
        AND facture.mois = mois
        AND facture.annee = annee
        AND facture.identifiant = identifiant;


END
//
DELIMITER ;

那些是我的:

-- phpMyAdmin SQL Dump
-- version 4.0.4
-- http://www.phpmyadmin.net
--
-- Client: localhost
-- Généré le: Mer 02 Avril 2014 à 17:00
-- Version du serveur: 5.6.12-log
-- Version de PHP: 5.4.12

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Base de données: `reserv`
--
CREATE DATABASE IF NOT EXISTS `reserv` DEFAULT CHARACTER SET latin1 COLLATE     latin1_swedish_ci;
USE `reserv`;

-- --------------------------------------------------------

--
-- Structure de la table `association`
--

CREATE TABLE IF NOT EXISTS `association` (
  `association` int(11) NOT NULL AUTO_INCREMENT,
  `libelle` char(32) NOT NULL,
  PRIMARY KEY (`association`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

-- --------------------------------------------------------

--
-- Structure de la table `facture`
--

CREATE TABLE IF NOT EXISTS `facture` (
  `association` int(11) NOT NULL,
  `annee` int(11) NOT NULL,
  `mois` int(11) NOT NULL,
  `identifiant` int(11) NOT NULL,
  `quota` int(11) NOT NULL,
  `montant` int(11) NOT NULL,
  PRIMARY KEY (`association`,`mois`,`annee`,`identifiant`),
  KEY `i_fk_facture_mois` (`mois`,`annee`),
  KEY `i_fk_facture_association` (`association`),
  KEY `facture_ibfk_1` (`annee`,`mois`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Structure de la table `heure`
--

CREATE TABLE IF NOT EXISTS `heure` (
  `numero` int(11) NOT NULL,
  `association` int(11) NOT NULL,
  `code` int(11) NOT NULL,
  `annee` int(11) NOT NULL,
  `mois` int(11) NOT NULL,
  `jour` int(11) NOT NULL,
  `heure` int(11) NOT NULL,
  PRIMARY KEY (`numero`,`association`,`code`,`annee`,`mois`,`jour`,`heure`),
  KEY `i_fk_heure_mois` (`annee`,`mois`),
  KEY `i_fk_heure_reservation` (`numero`,`association`,`code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Structure de la table `mois`
--

CREATE TABLE IF NOT EXISTS `mois` (
  `mois` int(11) NOT NULL,
  `annee` int(11) NOT NULL,
  PRIMARY KEY (`annee`,`mois`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Structure de la table `reservation`
--

CREATE TABLE IF NOT EXISTS `reservation` (
  `numero` int(11) NOT NULL,
  `association` int(11) NOT NULL,
  `code` int(11) NOT NULL,
  PRIMARY KEY (`numero`,`association`,`code`),
  KEY `i_fk_reservation_association` (`association`),
  KEY `i_fk_reservation_salle` (`numero`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


-- --------------------------------------------------------

--
-- Structure de la table `salle`
--

CREATE TABLE IF NOT EXISTS `salle` (
  `numero` int(11) NOT NULL AUTO_INCREMENT,
  `capacite` int(11) NOT NULL,
  `tarif` int(11) NOT NULL,
  PRIMARY KEY (`numero`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Contraintes pour les tables exportées
--

--
-- Contraintes pour la table `facture`
--
ALTER TABLE `facture`
  ADD CONSTRAINT `facture_ibfk_1` FOREIGN KEY (`annee`, `mois`) REFERENCES `mois`     (`annee`, `mois`),
  ADD CONSTRAINT `facture_ibfk_2` FOREIGN KEY (`association`) REFERENCES `association`     (`association`);

--
-- Contraintes pour la table `reservation`
--
ALTER TABLE `reservation`
  ADD CONSTRAINT `reservation_ibfk_1` FOREIGN KEY (`association`) REFERENCES     `association` (`association`),
  ADD CONSTRAINT `reservation_ibfk_2` FOREIGN KEY (`numero`) REFERENCES `salle`     (`numero`);

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

请告诉我如何修复它,因为触发器无法正常工作。

1 个答案:

答案 0 :(得分:1)

我看到的一个问题是这个条件测试:

IF (identifiant = null)

永远不会返回TRUE。如果要测试变量是否设置为NULL值,请使用IS NULL运算符。

IF (identifiant IS NULL)

我从未使用查询作为变量的DEFAULT值。 (这可能是有效的,我以前从未见过这样做过。)

我的代码是这样的:

DECLARE nombreHeure INT;
SELECT COUNT(heure.numero) INTO nombreHeure
  FROM heure
 WHERE heure.code = NEW.code;

您要将查询结果分配到变量的任何位置,您需要确保查询不会返回多行。上面的查询将返回一行(假设,它不会抛出错误),所以没关系。

对于你的触发器中的很多其他查询,不清楚(对于不经意的读者)这些只返回一行。


另一个大问题似乎是局部变量与SQL语句中的列具有相同的名称。 MySQL不会将其视为对变量的引用,它会将其视为对的引用。 (当MySQL遇到SQL语句中的标识符时,它首先检查它是否是一个列,只有当它找不到该名称的列时才认为它可能是一个变量。)

例如:

AND facture.mois = mois

对于右侧的mois的引用,MySQL首先在其中一个表(来自范围内的任何行源)中查找一个名为该列的列,然后将其视为变量。在这种情况下,它会在mois中找到facture作为列,因此SQL基本上等同于:

AND facture.mois = fracture.mois

实际上与:

相同
AND facture.mois IS NOT NULL

基本上,您需要确保SELECT语句中使用的变量名与查询引用的表中的所有列名不同