2012-06-09 92 views
0

我正在开发一个简单的网络聊天服务器。我有两个表:
chatMsgs:在删除之前插入MySQL

  • ROWID
  • 用户名
  • 时间
  • 行动
  • 目标
  • 消息

个onlineUsers:

  • 用户名
  • 行动
  • LastActive

我怎么会去从onlineUsers删除任何行,其中online.LastActive <%T%-120和任何物品取出来自onlineUsers,我想添加一个新的行chatMsgs

Username=onlineUsers.username, 
LastAction='logout', 
Time=%t%, 
Message='Timed out after 2min' 

%t%只是一个将被php的time()返回值替换的占位符。如果可能的话,我想通过一次调用mysqli_query处理程序来完成此操作,尽管查询字符串可以包含针对mysql服务器的多个指令。

以下工作afaik(没有经过全面测试),但我是不知道是否有更好的方法:

<?php 
    // $db is an mysqli database link. 

    $t = time() 
    $e = $t - 120, 
    $q = "SELECT Username FROM onlineUsers WHERE LastActive<={$e};", 
    $r = $db->query($q); 

    if (!$r) 
     die('db error'); 

    elseif ($r->num_rows > 0) { 
     $q = ''; 

     $r = $r->fetch_all(MYSQLI_NUM); 
     for ($n in $r) 
      $q .= "INSERT INTO chatMsg(Username,Time,Action,Message) VALUES('{$n}',{$t},'Logout','Timed out after 2min');"; 

     $q .= "DELETE FROM onlineUsers WHERE LastActive<={$e};"; 

     $r = $db->query($q); 
     if (!$r) 
      die('db error'); 
    } 
?> 
+1

呃,两句话呢?你有什么尝试? –

回答

1

如果你想做到这一切在一个单一的SQL语句,那么以下就足够了(使用$ t和$来自以上的变量):

INSERT INTO chatMsg(Username, Time, Action, Message) 
SELECT Username, {$t}, 'logout', 'Timed out after 2 mins' 
FROM onlineUsers 
WHERE LastActive <= {$e}; 

DELETE FROM onlineUsers WHERE LastActive <= {$e}; 

请注意,竞争条件可能发生 - 如果用户在INSERT和DELETE语句之间执行某些活动,它们仍将从onlineUsers表中删除。你可以绕过这个加载所有“被删除”的条目,首先调用删除,然后添加注销消息,但这与你原来的要求相反。

+0

我只是想能够更新chatMsgs表,并从同一语句中的onlineUsers中删除用户。处理顺序对我无关紧要。我将如何去扭转它,所以删除可能发生在插入之前,不会导致竞争状态? – SReject

0

SQL查询:

INSERT INTO chatMsgs 
VALUES ($username, $time, "logout", $target, $message); 

DELETE FROM onlineUsers 
WHERE Username = $username;