这个MySQL触发排名有什么问题?

时间:2014-01-13 17:31:53

标签: mysql sql triggers

我正在尝试编写一个触发器,将表中的所有条目从1到10排列(最大值具有等级10,最小值具有等级1,所有其他值都被赋予其间的整数值)。这是触发器代码:

DELIMITER $$
CREATE TRIGGER risks_before_insert BEFORE INSERT ON risks
FOR EACH ROW
BEGIN

DECLARE n_project_id integer; #project_id associated with risk
DECLARE max_cost double; #previous maximum expected_cost in project
DECLARE min_cost double; #previous minimum expected_cost in project
DECLARE max_impact double; #previous maximum impact_effect in project
DECLARE min_impact double; #previous minimum impact_effect in project
DECLARE slope double; #slope for prioritizing function

SELECT t.project_id INTO n_project_id FROM tasks t WHERE t.task_id = NEW.task_id; #GET PROJECT_ID ASSOCIATED WITH THE RISK

SET NEW.expected_cost = NEW.probability * NEW.cost_impact, NEW.overall_impact = NEW.probability * NEW.impact_effect; #CALCULATE EXPECTED_COST AND OVERALL_IMPACT FIELDS

SELECT MAX(expected_cost), MIN(expected_cost), MAX(overall_impact), MIN(overall_impact) INTO max_cost, min_cost, max_impact, min_impact FROM view_risks WHERE r.project_id = n_project_id; #GET EXTREME VALUES FROM TABLE, STORE IN MEMORY

/*
Update Priority Monetary Rankings
*/
IF (max_cost IS NULL OR min_cost IS NULL) THEN #check for empty table
    SET NEW.priority_monetary = 10;
ELSEIF ((NEW.expected_cost <= max_cost) AND (NEW.expected_cost >= min_cost)) THEN 
#NEW VALUE DOES NOT CHANGE TABLE EXTREMES
    IF (max_cost - min_cost = 0) THEN
        SET NEW.priority_monetary = 10;
    ELSE
        SET slope = 9 / (max_cost - min_cost);
SET NEW.priority_monetary = slope * (NEW.expected_cost - min_cost) + 1;
    END IF;
ELSEIF (NEW.expected_cost > max_cost) THEN
    SET NEW.priority_monetary = 10;
    SET slope = 9 / (NEW.expected_cost - min_cost);
    UPDATE risks SET priority_monetary = slope * (expected_cost - min_cost) + 1 WHERE project_id = n_project_id;
ELSE #NEW VALUE CORRESPONDS TO A MINIMUM
    SET NEW.priority_monetary = 1;
    SET slope = 9 / (max_cost - NEW.expected_cost);
    UPDATE risks SET priority_monetary = slope * (expected_cost - min_cost) + 1 WHERE project_id = n_project_id;
END IF;

/*
Update Priority Effect Rankings
*/
IF (max_impact IS NULL OR min_impact IS NULL) THEN #check for empty table
    SET NEW.priority_effect = 10;
ELSEIF ((NEW.overall_impact <= max_impact) AND (NEW.overall_impact >= min_impact)) THEN 
#NEW VALUE DOES NOT CHANGE TABLE EXTREMES
    IF (max_cost - min_cost = 0) THEN
        SET NEW.priority_effect = 10;
    ELSE
        SET slope = 9 / (max_impact - min_impact);
SET NEW.priority_effect = slope * (NEW.overall_impact - min_impact) + 1;
    END IF;
ELSEIF (NEW.overall_impact > max_impact) THEN
    SET NEW.priority_effect = 10;
    SET slope = 9 / (NEW.overall_impact - min_impact);
    UPDATE risks SET priority_effect = slope * (overall_impact - min_impact) + 1 WHERE project_id = n_project_id;
ELSE #NEW VALUE CORRESPONDS TO A MINIMUM
    SET NEW.priority_effect = 1;
    SET slope = 9 / (max_impact - NEW.overall_impact);
    UPDATE risks SET priority_effect = slope * (overall_impact - min_impact) + 1 WHERE project_id = n_project_id;
END IF;
END
DELIMITER ;

但是,我收到以下错误:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5 

任何人都可以解释什么是错的吗?供您参考,我的排名算法由以下函数描述,常量为maxval和minval:

Rank(x)= 1 + slope(x - minval),其中slope = 9 /(maxval - minval)。

谢谢!

其他信息:

字段类型: expected_cost =&gt;十进制(11,2) priority_monetary =&gt; TINYINT(2)

样本值: expected_cost =&gt; 1000.00 priority_monetary =&gt; 2

2 个答案:

答案 0 :(得分:1)

在我的MySql客户端中,您的缺点不会显示为缺点,也会进行一些小修改(UPDATE tableName不带关键字TABLE)

DELIMITER $$
CREATE TRIGGER risks_before_insert
BEFORE INSERT ON risks
FOR EACH ROW
BEGIN

DECLARE max_cost double; #previous maximum expected_cost in project
DECLARE min_cost double; #previous minimum expected_cost in project
DECLARE slope double; #slope for prioritizing functioN

SELECT MAX(expected_cost), MIN(expected_cost) INTO max_cost, min_cost FROM view_risks; #GET EXTREME VALUES FROM TABLE, STORE IN MEMORY

/*
Update Priority Monetary Rankings
*/
IF (max_cost IS NULL OR min_cost IS NULL) THEN #check for empty table
    SET NEW.priority_monetary = 10;
ELSE IF ((NEW.expected_cost <= max_cost) AND (NEW.expected_cost >= min_cost)) THEN #NEW VALUE DOES NOT CHANGE TABLE EXTREMES
    IF (max_costs - min_cost = 0) THEN
        SET NEW.priority_monetary = 10;
    ELSE
        SET slope = 9 / (max_cost - min_cost);
        SET NEW.priority_monetary = slope * (NEW.expected_cost - min_cost) + 1;
    END IF;
ELSE IF (NEW.expected_cost > max_cost) THEN
    SET NEW.priority_monetary = 10;
    SET slope = 9 / (NEW.expected_cost - min_cost);
    UPDATE risks SET priority_monetary = slope * (expected_cost - min_cost) + 1;
ELSE #NEW VALUE CORRESPONDS TO A MINIMUM
    SET NEW.priority_monetary = 1;
    SET slope = 9 / (max_cost - NEW.expected_cost);
    UPDATE risks SET priority_monetary = slope * (expected_cost - NEW.min_cost) + 1;
END IF;
END $$
DELIMITER ;

答案 1 :(得分:1)

你有ELSE IF,你应该在哪里使用ELSEIF。

同样@Mihai写道:你的缺点不会显示为缺点,并且在UPDATE之后你有关键字TABLE(应该只有UPDATE tableName)。

PS 我建议您使用MySql的某些工具,例如MySql Workbench,它有Windows的分发版,大多数Linux系统和OSX。它会让你更好地工作并检查你的语法。

更改后的代码:

DELIMITER $$
CREATE TRIGGER risks_before_insert
BEFORE INSERT ON risks
FOR EACH ROW
BEGIN

DECLARE max_cost double; #previous maximum expected_cost in project
DECLARE min_cost double; #previous minimum expected_cost in project
DECLARE slope double; #slope for prioritizing functioN

SELECT MAX(expected_cost), MIN(expected_cost) INTO max_cost, min_cost FROM view_risks; #GET EXTREME VALUES FROM TABLE, STORE IN MEMORY

/*
Update Priority Monetary Rankings
*/
IF (max_cost IS NULL OR min_cost IS NULL) THEN #check for empty table
    SET NEW.priority_monetary = 10;
ELSEIF ((NEW.expected_cost <= max_cost) AND (NEW.expected_cost >= min_cost)) THEN #NEW VALUE DOES NOT CHANGE TABLE EXTREMES
    IF (max_cost - min_cost = 0) THEN
        SET NEW.priority_monetary = 10;
    ELSE
        SET slope = 9 / (max_cost - min_cost);
        SET NEW.priority_monetary = slope * (NEW.expected_cost - min_cost) + 1;
    END IF;
ELSEIF (NEW.expected_cost > max_cost) THEN
    SET NEW.priority_monetary = 10;
    SET slope = 9 / (NEW.expected_cost - min_cost);
    UPDATE risks SET priority_monetary = slope * (expected_cost - min_cost) + 1;
ELSE #NEW VALUE CORRESPONDS TO A MINIMUM
    SET NEW.priority_monetary = 1;
    SET slope = 9 / (max_cost - NEW.expected_cost);
    UPDATE risks SET priority_monetary = slope * (expected_cost - NEW.min_cost) + 1;
END IF;

END $$
DELIMITER ;