0

我有一个页面,其中有多个简单的输入供用户选择信息更新选项。用户可能尚未定义更新配置文件,因此我尝试使用“INSERT INTO ... ON DUPLICATE KEY UPDATE”语句。我也在尝试使用 sprintf 来避免可能的 SQL 注入问题。我的问题是我无法开始弄清楚如何编写 SQL 语句。这是代码的相关部分。

$updateSQL = sprintf("INSERT INTO reminders_cfg 
                    (id, day_of, day_of_advance, day_prior, default_time, week_prior, 2_week_prior, 3_week_prior, 4_week_prior, 5_week_prior, day_after, 2_week_after, 50_day_after) 
                    VALUES %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
                    ON DUPLICATE KEY UPDATE ",
                   GetSQLValueString($jeweler, "text"),
                   GetSQLValueString($_POST['DayOf'], "text"),
                   GetSQLValueString($_POST['Advance'], "text"),
                   GetSQLValueString($_POST['DayPrior'], "text"),
                   GetSQLValueString($_POST['Time'], "text"),
                   GetSQLValueString($_POST['WeekPrior'], "text"),
                   GetSQLValueString($_POST['2WeeksPrior'], "text"),
                   GetSQLValueString($_POST['3WeeksPrior'], "text"),
                   GetSQLValueString($_POST['4WeeksPrior'], "text"),
                   GetSQLValueString($_POST['5WeeksPrior'], "text"),
                   GetSQLValueString($_POST['DayAfter'], "text"),
                   GetSQLValueString($_POST['2WeeksAfter'], "text"),
                   GetSQLValueString($_POST['50DaysAfter'], "text"));

这是在 Dreamweaver 中完成的 PHP 页面。这就是 GetSQLValueString 函数的用武之地。我真的不知道在实际的“ON DUPLICATE KEY UPDATE”部分之后要做什么,以便不必再次复制所有变量和占位符。我希望这是有道理的。

更新:好的。这是我最新的尝试,但仍然无法正常工作。

if ((isset($_POST["MM_update"])) && ($_POST["MM_update"] == "form1")) {
    $stmt = $mysqli->prepare("INSERT INTO reminders_cfg 
                    (id, day_of, day_of_advance, day_prior, default_time, week_prior, 2_week_prior, 3_week_prior, 4_week_prior, 5_week_prior, day_after, 2_week_after, 50_day_after) 
                    VALUES :id, :day_of, :day_of_advance, :day_prior, :default_time, :week_prior, :2_week_prior, :3_week_prior, :4_week_prior, :5_week_prior, :day_after, :2_week_after, :50_day_after
                    ON DUPLICATE KEY UPDATE day_of = :day_of, day_of_advance = :day_of_advance, day_prior = :day_prior, default_time = :default_time, week_prior = :Week_prior, 2_week_prior = :2_week_prior, 3_week_prior = :3_week_prior, 4_week_prior = :4_week_prior, 5_week_prior = :5_week_prior, day_after = :day_after, 2_week_after = :2_week_after, 50_day_after = :50_day_after")
                    or die($mysqli->error);
    $stmt->bindParam(':id', $jeweler, PDO::PARAM_INT);      
    $stmt->bindParam(':day_of', $_POST['DayOf'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':day_of_advance', $_POST['Advance'], PDO::PARAM_INT);
    $stmt->bindParam(':day_prior', $_POST['DayPrior'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':default_time', $_POST['Time'], PDO::PARAM_STR, 9);
    $stmt->bindParam(':week_prior', $_POST['WeekPrior'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':2_week_prior', $_POST['2WeeksPrior'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':3_week_prior', $_POST['3WeeksPrior'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':4_week_prior', $_POST['4WeeksPrior'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':5_week_prior', $_POST['5WeeksPrior'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':day_after', $_POST['DayAfter'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':2_week_after', $_POST['2WeeksAfter'], PDO::PARAM_STR, 6);
    $stmt->bindParam(':50_day_after', $_POST['50DaysAfter'], PDO::PARAM_STR, 6);

    $stmt->execute() or die("Insert query error: " . mysql_error());
    $stmt->close(); 
}

这会产生一个 SQL 语法错误,因为我对这个“插入到......在重复密钥更新”上是新手,所以我有点卡住了。这是错误...

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 3 行的 ':id, :day_of, :day_of_advance, :day_prior, :default_time, :week_prior, :2_week_p' 附近使用正确的语法

4

2 回答 2

1

ON DUPLICATE KEY UPDATE您只放置要更新的值并保留应该保持不变的值之后。例如

纯mysql示例

insert into my_table(name, lastSeen, salary)
              values("Some Name", now(), 25334)
on duplicate key update salary = 25334, lastSeen = now()

nameprimary key针对此示例,现在假设数据库中已经存在同名的记录,则该条目将通过更改薪水和 lastSeen 来更新。如果不是,则将使用提供的值创建条目。在声明的第一部分

insert into my_table(name, lastSeen, salary) values("Some Name", now(), 25334)

希望有帮助。

另外,如果您在问题中添加了要在重复键上更新的字段,那就太好了,这样我们就可以使用您的代码来回答您的问题

编辑 好的,我知道这不是有史以来最好的格式化代码,但这可能有帮助吗?(也许那里有语法错误,但如果这是你想要的,你可能明白了)

 $updateSQL = sprintf("INSERT INTO reminders_cfg 
                (id, day_of, day_of_advance, day_prior, default_time, 
                 week_prior, 2_week_prior, 3_week_prior, 4_week_prior,
                 5_week_prior, day_after, 2_week_after, 50_day_after) 
                VALUES %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s
                ON DUPLICATE KEY UPDATE id = %s, day_of = %s, day_of_advance = %s, 
                     day_prior = %s, default_time = %s, week_prior = %s,
                     2_week_prior = %s, 3_week_prior = %s, 4_week_prior = %s,
                     5_week_prior = %s, day_after = %s, 2_week_after = %s, 
                     50_day_after = %s ",
               GetSQLValueString($jeweler, "text"),
               GetSQLValueString($_POST['DayOf'], "text"),
               GetSQLValueString($_POST['Advance'], "text"),
               GetSQLValueString($_POST['DayPrior'], "text"),
               GetSQLValueString($_POST['Time'], "text"),
               GetSQLValueString($_POST['WeekPrior'], "text"),
               GetSQLValueString($_POST['2WeeksPrior'], "text"),
               GetSQLValueString($_POST['3WeeksPrior'], "text"),
               GetSQLValueString($_POST['4WeeksPrior'], "text"),
               GetSQLValueString($_POST['5WeeksPrior'], "text"),
               GetSQLValueString($_POST['DayAfter'], "text"),
               GetSQLValueString($_POST['2WeeksAfter'], "text"),
               GetSQLValueString($_POST['50DaysAfter'], "text"),
               GetSQLValueString($jeweler, "text"),
               GetSQLValueString($_POST['DayOf'], "text"),
               GetSQLValueString($_POST['Advance'], "text"),
               GetSQLValueString($_POST['DayPrior'], "text"),
               GetSQLValueString($_POST['Time'], "text"),
               GetSQLValueString($_POST['WeekPrior'], "text"),
               GetSQLValueString($_POST['2WeeksPrior'], "text"),
               GetSQLValueString($_POST['3WeeksPrior'], "text"),
               GetSQLValueString($_POST['4WeeksPrior'], "text"),
               GetSQLValueString($_POST['5WeeksPrior'], "text"),
               GetSQLValueString($_POST['DayAfter'], "text"),
               GetSQLValueString($_POST['2WeeksAfter'], "text"),
               GetSQLValueString($_POST['50DaysAfter'], "text"));
于 2013-01-09T04:21:52.883 回答
-1

ON DUPLICATE KEY UPDATE当存在一个可能的冲突键时才应使用。在这种情况下,我猜是ID。

您最好定义一个触发器。像这样的东西:

CREATE TRIGGER `reminders_cfg_duplicates` BEFORE INSERT ON `reminders_cfg` FOR EACH ROW
  DELETE FROM `reminders_cfg` WHERE `id`=new.`id`;

运行一次,例如从 phpMyAdmin 的控制面板。然后,数据库将自动删除任何导致重复的行,允许插入新行而不必在更新中复制所有值。

于 2013-01-09T04:16:32.927 回答