我正在尝试使用未引用的参数(案例 1、1A)以类似 PDO 的样式使用准备好的语句执行原始查询,无论如何它都会引发异常:
执行 'SELECT * FROM pages WHERE title LIKE :title' 时发生异常:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 ':title' 附近使用正确的语法
此外,引用命名参数不起作用(案例 2),它不会引发异常,但也找不到任何东西。
根据需要使用未命名/编号和未引用的参数(案例 3、3A)或executeQuery()
代替prepare()
(案例 4)。特别是我想使用命名参数,最后一个是我的选择。
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
...
public function queryPagesByTitle(string $title = null): array
{
/** @var Connection $conn */
$conn = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages');
// Case 1: DOESN'T work with non-quoted params
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE :title");
$stmt->execute(['title' => $title]);
// Case 1A: DOESN'T work with non-quoted params
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE :title");
$stmt->bindValue('title', $title, \PDO::PARAM_STR);
$stmt->execute();
// Case 1B: DOESN'T work with non-quoted,unique params
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE :dcUniqueParam");
$stmt->bindParam('dcUniqueParam', $title, \PDO::PARAM_STR);
$stmt->execute();
// Case 1C: DOESN'T work with non-quoted,unique params even with :colon while binding
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE :dcUniqueParam");
$stmt->bindParam(':dcUniqueParam', $title, \PDO::PARAM_STR);
// Case 2: DOESN'T work with quoted params neither, doesn't throw an exception, but doesn;t find anything
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE ':title'");
$stmt->execute(['title' => $title]);
// Case 3: Works with numbered param(s)
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE ?");
$stmt->execute([1 => $title]);
// Case 3A: Works with numbered param(s)
$stmt = $conn->prepare("SELECT * FROM pages WHERE title LIKE ?");
$stmt->bindParam(1, $title, \PDO::PARAM_STR);
$stmt->execute();
// Case 4: Works with non-quoted named param(s)
$stmt = $conn->executeQuery(
"SELECT uid, title FROM pages WHERE title LIKE :title",
['title' => $title],
[\PDO::PARAM_STR]
);
return $stmt->fetchAll(FetchMode::ASSOCIATIVE);
}
几个问题
- 为什么第一个案例在 PDO 继承之后不能像我预期的那样工作,或者 Doctrine实际上是如何做到的?
executeQuery()
使用而不是有一些缺点(如果有的话)prepare()
吗?- 我应该使用
prepare()
带编号的参数吗? - 使用原始查询而不是 QueryBuilder 之间有什么显着区别吗?
笔记
我知道,为了正确使用模型数据和存储库,我可以/应该使用通用的 QueryBuilder 接口。这种情况适用于我的数据库中不使用数据映射的一些原始数据,我正在寻找一些性能改进。pages
表在这里仅用于演示概念。