doushang1890 2015-06-23 02: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 04: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.

    展开全部

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

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部