在一个查询中更新(或插入)多行

时间:2014-05-08 20:55:38

标签: php mysql sql sql-insert

我正在尝试一次更新表中的多行(如果它们不存在则插入它们)给定设置和一组用户ID。

我如何从settings表中为特定帐户的特定计算机的所有用户选择所有行的示例。这是我需要插入值的结果集,如果存在则需要更新。

$stmt = $db->prepare("      
    SELECT settings.*
    FROM
        ( SELECT  account_id, computer_id
            FROM computers
            ORDER BY computer_id ASC LIMIT 0, ".$_SESSION['user']['licenses']."
        ) as c
        LEFT JOIN users
            on users.computer_id = c.computer_id
        LEFT JOIN accounts
            on accounts.account_id = c.account_id
        LEFT JOIN settings
            on settings.user_id = users.user_id
    WHERE accounts.account_id = ".$_SESSION['user']['account_id']."
");

我想做什么: 我正在尝试更新/插入settings表中的三列(enabled,status和user_id),仅用于列出阵列中列出的那些用户ID。所有人的启用状态和状态值都相同,但每个用户ID都不同。

$ users = array(12,36,43,56,76)

$ binding = array(     '启用' => 1,     '状态' => 2,     ' USER_ID' => 来自数组     );

如果我的思维过程是正确的,我可以从上面列出的语句创建一个虚拟表,然后使用ON DUPLICATE KEY UPDATE来插入/更新该虚拟表的结果?

这可能吗?如果是这样,示例,提示或指向正确的方向?我工作的方式涉及给定数组中每个用户id的foreach循环,因此根据其计数将有x个查询。如果我能把它切成只有一个会很棒的那个!

更新

好吧,我现在完全感到困惑...这是对定义值的尝试,这是无效的......我仍然需要一种方法来为我的数组中的每个user_id这样做,如上所述。我不需要保存'我的整个FROM子句也是一个新的引用?

$stmt = $db->prepare("
    INSERT INTO settings (user_id, enabled, status)
    VALUES (:user_id, :enabled, :alert_user)    
    SELECT user_id, enabled, status
    FROM
        ( SELECT  account_id, computer_id
            FROM computers
            ORDER BY computer_id ASC LIMIT 0, ".$_SESSION['user']['licenses']."
        ) as c
        LEFT JOIN users
            on users.computer_id = c.computer_id
        LEFT JOIN accounts
            on accounts.account_id = c.account_id
        LEFT JOIN settings
            on settings.user_id = users.user_id
        WHERE accounts.account_id = ".$_SESSION['user']['account_id']."
    ON DUPLICATE KEY UPDATE enabled = VALUES(enabled), status = VALUES(status)  
");

$binding = array(
    'enabled' => 1,
    'alert_user' => 4,
    'user_id' => 6
    );

$stmt->execute($binding);

1 个答案:

答案 0 :(得分:1)

是的,你的想法是正确的。它应该是这样的:

INSERT INTO settings (user_id, enabled, status)
SELECT user_id, enabled, status
FROM ... -- rest of your query here
ON DUPLICATE KEY UPDATE enabled = VALUES(enabled), status = VALUES(status)
VALUES(colname)子句中的

ON DUPLICATE KEY UPDATE获取了在没有重复时插入的值。

好的,根据您的评论,我认为这可能是您想要的:

INSERT INTO settings (user_id, enabled, status)
SELECT :user_id, :enabled, :status
FROM ...
JOIN ...
JOIN ...
WHERE ...
ON DUPLICATE KEY UPDATE enabled = VALUES(enabled), status = VALUES(status)

如果连接返回任何行,则会插入或更新指定的行。如果它没有找到任何行,则不会进行插入/更新。

如果您在要加入的表中没有匹配项时不想要返回任何内容,则应该使用内部联接而不是左联接。