doushang1890 2015-06-23 10:37
浏览 88
已采纳

功能/触发器已在使用中?

Im having problems getting an update function to work. The function marks badges as seen so that they are hidden from a notification window.

The function is called when the user clicks a button to mark them as seen.

I have two triggers on the table its trying to update which I think may be causing the problem.

The problem is : Can't update table 'users' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Triggers:

enter image description here

Function:

function markAsSeen() {
        require "connect.php"; 

    $seen = mysqli_query($connection,"Update userbadges 
INNER JOIN users ON users.id = userbadges.user_id
SET seen='1'
WHERE studentid = '".$_SESSION["studentid"]."' && seen=0")  or die(mysqli_error($connection));

  while ($data = mysqli_fetch_array($seen)) {

echo 'Done';


  }
}

Is there any way around this?

  • 写回答

1条回答 默认 最新

  • douxun4860 2015-06-23 12:57
    关注

    Your issue is that the update_users_trigger trigger makes changes to the contents of the table users, while the query that is triggering the execution of this trigger also uses the table users.

    You will need to adjust your query so that this deadlock doesn't occur. It isn't clear which fields are from each table, but I suspect that in your initial query you need to join on users so that you can query on studentid.

    You could create a different function to get the userID that you need something like the following:

    require_once "connect.php";
    function getUserIDFromStudentID($student_id, mysqli $connection)
    {
        $query = 'SELECT id FROM users WHERE studentid = ? LIMIT 1';
        $stmt = $connection->prepare($query);
        // Replace the below s to an i if it's supposed to be an integer
        $stmt->bind_param("s", $student_id);
        $stmt->execute();
        $result = $stmt->get_result();
        $record = $result->fetch_object();
        $result->free();
        if ($record) {
            return $record->id;
        }
    }
    
    function markAsSeen(mysqli $connection) {
        $user_id = getUserIDFromStudentID($_SESSION["studentid"], $connection);
        if (! $user_id) {
            throw new Exception('Unable to get user id');
        }
        $seen_query = 'UPDATE userbadges SET seen = 1 WHERE user_id = ? and seen = 0';
        $stmt = $connection->prepare($seen_query);
        // Replace the below s to an i if it's supposed to be an integer
        $stmt->bind_param("s", $user_id);
        $result = $stmt->execute();
        if (! $result) {
            die(mysqli_error($connection));
        }
        echo 'Done';
    }
    

    Passing the connection object around rather than requiring a global file to be required every time will allow for more flexibility.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题
  • ¥15 ad5933的I2C
  • ¥15 请问RTX4060的笔记本电脑可以训练yolov5模型吗?
  • ¥15 数学建模求思路及代码