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.

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

报告相同问题?

悬赏问题

  • ¥15 Matlab在app上输入带有矩阵形式的初始条件发生错误
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址
  • ¥15 elmos524.33 eeprom的读写问题
  • ¥15 用ADS设计一款的射频功率放大器