简单 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 模式,您也可以使用 "(双引号)。
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();
我似乎无法弄清楚问题出在哪里。我对交易还很陌生,看来我需要一个来插入下一个自动递增的 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 模式,您也可以使用 "(双引号)。
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();