【问题标题】:Error Inserting/Updating a row in a Database using SQL, Php and Ajax使用 SQL、Php 和 Ajax 在数据库中插入/更新行时出错
【发布时间】:2016-04-15 01:20:52
【问题描述】:

更新

我收到的 SQL 错误是:

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE (fb_id) = ('1018762834552473') ON DUPLICATE KEY UPDATE score='69139'' at line 1


我正在为 Javascript 游戏创建排行榜表,并且我目前正尝试在某个 Javascript 函数运行时将玩家的得分插入我的数据库。

我正在使用 Php 使用 Ajax Post 执行此操作。我在 Ajax 的成功区域中放了一个 console.log,它出现了,我认为这意味着 php 文件运行正常,但是数据库中的分数没有更新,所以我认为可能有我的 SQL 代码有错误。

这是 Ajax 帖子:

$.ajax({
 url: 'scripts/sendscore.php',
data: {'userid' : userid, 'score' : totalscore},
type: "POST",
success: function(response){    
         if (response.error) {
   console.log('Score input error - ' + response.error.message);
 }
 else {
 console.log("Score should be inputted correctly.");
}
}});

排行榜是针对 Facebook 游戏的,所以我在 Post 中发送了两件事,它们是:分数和用户 ID。

我希望 php 代码将分数输入到数据库中,其中发送的用户 id 与数据库中的用户 id 匹配,为了简化,我希望它用新分数插入/更新玩家的分数(玩家数据库中不应该有多个分数,它们应该只有一个分数)。这是我用来尝试实现此目的的 SQL:

<?php

$servername = "myserver";
$username = "myusername";
$password = "mypassword";
$dbname = "mydbname";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $conn->prepare("INSERT INTO scoretable (score) VALUES(:score) WHERE (fb_id) = (:userid) ON DUPLICATE KEY UPDATE score=:score");

$stmt->bindParam(':userid', $userid);
$userid = $_POST['userid'];
$stmt->bindParam(':score', $score);
$score = $_POST['score'];
$stmt->execute(); 
    }
catch(PDOException $e)
{
    echo "Error: " . $e->getMessage();
}
$conn = null;
?>

数据库表由两列组成,如下所示:

scoretable
========= 
fb_id
score

我收到消息“应正确输入分数”。回到控制台,所以我认为问题可能出在 SQL 行上?

对此的任何帮助将不胜感激,在此先感谢您!

【问题讨论】:

  • 我建议添加一种方法,以便在将查询发送到数据库之前在屏幕上查看查询。这样您就可以检查查询以确保它符合您的要求。
  • 在查询的最后检查分数,并且你能输出查询它到底试图执行什么吗? $stmt = $conn->prepare("INSERT INTO scoretable (score) VALUES(:score) WHERE (fb_id) = (:userid) ON DUPLICATE KEY UPDATE score= (:score) ");
  • 在 Firefox 中,您可以通过按 Ctrl + Shift + Q 来查看有关网络活动的详细信息,以检查 AJAX 对请求文件的响应
  • 嗨@PixelMaker 我在问题的开头添加了更新。看起来分数已正确发送到数据库,但实际 SQL 的语法错误。
  • 您好 @Koneko-Chan 和 chay22 感谢您的 cmets,我已经用 SQL 错误消息更新了我的问题。

标签: php sql ajax


【解决方案1】:

请注意,ON DUPLICATE KEY UPDATE 检查表中的每个唯一字段,而不仅仅是 PRIMARY 键。您希望 ON DUPLICATE KEY 匹配 UNIQUE 键的分数,那么您的 INSERT 将在没有 WHERE 子句的情况下正常工作。坏消息是 Mysql 不允许 where 重复键更新的子句,所以一个快速的技巧是使用 if 语句: 试试这个说法:

INSERT INTO `scoretable` (`score`) VALUES(:score) 
ON DUPLICATE KEY UPDATE 
`fb_id` = LAST_INSERT_ID(fb_id),
`score`= IF(VALUES(:score) >= score, VALUES(:score), score);

这里,fb_id 是一个自动增量字段,我不想被 UPDATE 修改;因此使用了 LAST_INSERT_ID 技巧。

【讨论】:

  • 嗨@mawia-hl 感谢您的回答,我想知道,使用ON DUPLICATE KEY UPDATE 有什么好处?我最近尝试了UPDATE scoretable SET score=(:score) WHERE fb_id=(:userid)这似乎工作正常(它用新分数替换玩家的分数而不是创建新行),使用这种方法会有什么问题,因为它看起来很简单?
  • 这取决于你想要做什么。如果该键的记录已存在,则 ON DUPLICATE KEY UPDATE 更新某个值。它是对 INSERT 语句的扩展。这个教程link有一个很好的例子。
【解决方案2】:

您正在为变量 $userid 和 $score 绑定后赋值。

【讨论】:

  • 你应该在绑定语句之前分配变量。
  • 嗨@sujata-halwai 感谢您的回复。我尝试将值的分配更改为绑定之前,但它仍然无法正常工作。我有其他 php 脚本,它们在绑定后分配变量,它们运行良好。我认为问题出在 Insert 语句本身,因为错误消息显示尝试插入它时出现的正确分数和 id。
【解决方案3】:

检查fb_id的数据类型和大小(可能无法保存你在数据库1018762834552473的数据类型的值)

【讨论】:

  • 嗨@pixel_maker,我刚刚检查了一下,它是 varchar(90),我所有的其他 php 脚本都可以完美地处理具有相同类型和长度的行的相同数据 (fb_id)。
  • 试试这个 INSERT INTO scoretable (score, fb_id) VALUES(:score, :userid) ON DUPLICATE KEY UPDATE score=:score
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 2011-07-10
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 2018-05-20
相关资源
最近更新 更多