简单 mysql 交易的语法错误

Syntax error with simple mysql transaction

我似乎无法弄清楚问题出在哪里。我对交易还很陌生,看来我需要一个来插入下一个自动递增的 ID。

查询如下:

START TRANSACTION;
INSERT INTO posts (title, text, user, club, time) 
VALUES ('$title', '$text', '$name', '$club', '$time');
INSERT INTO post_likes (user, post) 
VALUES ('$name', LAST_INSERT_ID());
COMMIT;

在 INSERT INTO 帖子之前语法错误打断了我。

引用时间和用户加反引号,是保留字:

START TRANSACTION;
INSERT INTO posts (title, text, `user`, club, `time`) VALUES ('$title', '$text', '$name', '$club', '$time');
INSERT INTO post_likes (user, post) VALUES ('$name', LAST_INSERT_ID());
COMMIT; 

如果开启了 ANSI SQL 模式,您也可以使用 "(双引号)。

See here

PDO 的 query()prepare() 方法每次执行仅支持单个 SQL 语句,但通过调用 START TRANSACTION/COMMIT,连同指向错误语法的错误消息 [= =15=],我们必须假设您正试图一次执行所有这些语句。这是行不通的,因为 PDO 不会在执行前用 ; 分隔符将它们分开。

PDO 提供 API 方法来处理代码中的事务,而不需要通过 PDO::beginTransaction() and PDO::commit() 执行 SQL 语句。所以你必须将两个INSERT语句分开,并将它们包装在事务方法中,调用query()prepare()/execute()两次。

// Assuming your PDO connection is $pdo...
$pdo->beginTransaction();
$pdo->query("INSERT INTO posts (title, text, user, club, time)  VALUES ('$title', '$text', '$name', '$club', '$time')");
$pdo->query("INSERT INTO post_likes (user, post)  VALUES ('$name', LAST_INSERT_ID())");
$pdo->commit();

现在,没有看到您的原始 PDO 代码,我假设您当前是如何直接使用变量执行它的。 我们可以做出重大改进

PDO 对准备好的语句有很好的支持,它提供了针对 SQL 注入的强大保护。如果您愿意,让我们将 prepare()/execute() using named parameters. Additionally, if you wish, you may substitute $pdo->lastInsertId() 的两个 query() 调用换成 MySQL 的原生 LAST_INSERT_ID()

$pdo->beginTransaction();

// Prepare the first statement
$stmt = $pdo->prepare('INSERT INTO posts (title, text, user, club, time) VALUES (:title, :text, :user, :club, :time)');
// Execute the statement with an array of bound values
$stmt->execute(array(':title' => $title, ':text' => $text, ':user' => $user, ':club' => $club, ':time' => $time));

// Prepare & execute the second one
$stmt = $pdo->prepare('INSERT INTO post_likes (user, post)  VALUES (:name, :post)');
$stmt->execute(array(':name' => $name, ':post' => $pdo->lastInsertId()));

// Commit it
$pdo->commit();