php - 重复键上的 Mysql 仅当 BlahVAl < BlahRowVal 时更新表

标签 php mysql sql key duplicates

我以前从未问过其中任何一个问题,我通常可以 思考或找到发布的想法的方法。 我尝试了我想到的方法,尝试使用一个 CASE 示例,看起来应该可行,但不行。无论如何都不会更新。

好的,这就是我正在尝试做的事情:

$Mysqlinfo="INSERT INTO `$PNum` (P_IDNum, P_Name, Raw_Time, Total_Time, T_Mode)
         VALUES ('$PersId', '$_POST[PersonaName]', '$Stats_Vals[1]',  '$Stats_Vals[2]', '$Stats_Vals[5]')
         ON DUPLICATE KEY UPDATE Car_Model='$Stats_Vals[1]', Total_Time='$Stats_Vals[5]', Raw_Time='$Stats_Vals[7]', T_Mode='$Stats_Vals[2]' (there was originally the "; at end here)
         ***WHERE Raw_Time > '$Stats_Vals[7]'";***

(那里有更多的名字,但我删除了一些,所以它不是太长,所以不要介意 $Stats_Vals 数字和结构)。

这件事在最后没有 WHERE 的情况下也能工作,除非它总是会插入或更新,不幸的是我知道Where不能与ON DUPLICATE KEY一起工作,所以什么是简单的等价物? 它必须检查 Val,如果条件不为 True,则不执行任何操作。

哦,是的,它的格式适合在 PHP 脚本中使用。 :0)

非常感谢您的帮助!

编辑 - 这是大部分 PHP/sql 代码,没有我想要实现的条件,它由应用程序调用:

<?php
hostname and
database info here
Variables, $_POST... etc.

 $link = mysql_connect($hostname, $username, $password);
        if (!$link) {
                die('Connection failed: ' . mysql_error());
        }
        else{
             echo "Connection to Server successful!" . PHP_EOL;  <for testing from web
}

        $db_selected = mysql_select_db($database, $link);
        if (!$db_selected) {
            die ('Can\'t select database: ' . mysql_error());
        }
        else {
            echo "Database successfully selected!". PHP_EOL;

$Mysqlinfo="INSERT INTO `$PNum` (P_IDNum, P_Name, Raw_Time, Total_Time, T_Mode)
         VALUES ('$PersId', '$_POST[PersonaName]', '$Stats_Vals[1]',  '$Stats_Vals[2]', '$Stats_Vals[5]')
         ON DUPLICATE KEY UPDATE Car_Model='$Stats_Vals[1]', Total_Time='$Stats_Vals[5]', Raw_Time='$Stats_Vals[7]', T_Mode='$Stats_Vals[2]'";

    if (!mysql_query($Mysqlinfo,$link))
              {
               mysql_close($link);
              die('Error: ' . mysql_error());
              }
}             
mysql_close($link);
?>

它可以工作,除了不遵循仅在 Raw_Time 较小​​时更新的条件之外。 再次感谢!

最佳答案

如果您想让更新成为有条件的,那么恐怕您无法使用 INSERT...ON DUPLICATE KEY UPDATE... 来完成此操作。您必须在两个或多个查询中完成此操作。为了使其原子化,您必须使用LOCK TABLES:

$primarykey = 'whatever';

query("LOCK TABLES mytable WRITE;");

$count = query("SELECT COUNT(*) FROM mytable WHERE id=?;", $primarykey);

if($count>0) // the ID already exists
{
    $time = query("SELECT Raw_time FROM mytable WHERE id=?;", $primarykey);
    if($time>$Stats_Vals[7])
        query("UPDATE mytable SET ... WHERE id=?;", $primarykey);
}
else
    query("INSERT INTO mytable ...");

query("UNLOCK TABLES;");

一些注意事项:

  1. 我在这里调用一些虚构的函数query,因为我不知道您使用什么方法来执行查询。我还缩写了一些查询,因为我懒得复制您的所有代码。您需要根据需要调整代码。

  2. 我还在查询中使用了 ? 作为参数 - 这是防止 SQL 注入(inject)的良好做法。

  3. LOCK TABLES 语句的作用是确保在您检查记录是否存在期间(SELECT COUNT( *)...) 以及您更新的时间。如果发生这种情况,您的代码将导致错误。

关于php - 重复键上的 Mysql 仅当 BlahVAl < BlahRowVal 时更新表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23399228/

相关文章:

PHP & 可湿性粉剂 : is_wp_error not working on try and catch

php - i18nFormat 与 CakePHP 3 - 为什么 YYYY 生成的年份与 yyyy 不同?

php - 如果表单中的值为空,如何显示警告消息

mysql - Django - SQLite 与 MySQL 上的 DateTimeField 查询

sql - 使用sql server将单行多列合并为一列

SQL Server - 'NOT NULL' 主键上的约束冗余?

php - SSL Cookie 中缺少安全标志 (http-cookie-secure-flag)

php - 哪个更有效的性能明智的价格 mysql 表的尺寸/产品或文本列中 csv 格式的价格

java - 在 mysql 查询中传递 java 字符串变量

mysql - 如果文件是.gz格式并且有不同的部分,如何恢复mysql数据库?