【问题标题】:MySql COUNT(*) is different in Stored ProcedureMySql COUNT(*) 在存储过程中是不同的
【发布时间】:2011-09-10 09:27:40
【问题描述】:

我正在开发一个“评分”系统,并试图通过使用一个存储过程来确保一个人不能两次提交评分,该存储过程将在允许一个新的项目之前检查一个人是否对特定项目进行了评分要保存的等级。奇怪的是,我传递了一个用户 ID 和对象 ID,但是当我的存储过程选择 COUNT(*) 时,我得到了错误的数字。

这是我的存储过程:

CREATE PROCEDURE `ADD_GRADE`(IN objectID int, IN grader int)
BEGIN
DECLARE gradeCount INT;

SELECT COUNT(*)
FROM GRADES
WHERE Obj_ID = objectID AND Grader = grader
INTO gradeCount;

IF gradeCount <= 0 THEN INSERT INTO Grades (Obj_ID, Grader) VALUES (objectID, grader);
END IF;

IF 语句正在运行,但由于某种原因,我的 GradeCount 似乎忽略了 Grader ID 并仅根据 Obj_ID 进行检查。我添加了选择以确保我的参数保持在正确的值,并且它们是。如果我只复制选择并在其他地方手动执行,我会得到正确的数字。

虽然是 MySql 的新手,但我对 SQL 本身并不陌生。我只是要疯了吗?还是我做错了什么?

谢谢

【问题讨论】:

  • 不确定问题出在哪里,但是你的逻辑太复杂了。 COUNT(*) 不能返回 IF gradecount < 1 THEN INSERT(IOW,如果该评分者和 obj_id 还没有行,则插入)。

标签: mysql sql stored-procedures


【解决方案1】:

即使此代码有效(我不知道为什么无效),它也不是确保某些内容只输入一次的正确方法。

正确的方法是对 objectID 和 Grader 列应用唯一约束。然后尝试插入行。如果行插入,则值是唯一的。如果你得到一个独特的违规,那么这些值已经被输入了。

如果您没有可用的唯一约束,您应该锁定表以确保您的命令之间没有其他更新发生。

【讨论】:

    【解决方案2】:

    我的猜测是因为 MySQL 对字段名和代码不区分大小写

    Grader = grader
    

    只是将列与自身进行比较,这始终是正确的。您可能需要重命名您传入的参数,使其与现有列的名称不同。我的所有存储过程参数通常都以 __(双下划线)开头,所以我不会遇到这种情况。

    【讨论】:

    • 我赞成这两个答案。 Scott Bruns 在最佳设计方面是正确的,但您对问题的技术答案也是正确的。将列与其自身进行比较正是正在发生的事情,并且计数将始终是 Obj_ID 等于 objectID 的行数,因为 AND 1 将始终评估为真。
    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多