【发布时间】:2020-11-17 22:17:04
【问题描述】:
我正在尝试使用未加引号的参数(案例 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 实际上如何 does it?
- 使用
executeQuery()代替prepare()是否有一些缺点(如果有)? - 我应该使用带有编号参数的
prepare()吗? - 使用原始查询代替 QueryBuilder 有什么显着区别吗?
注意
我知道,为了正确处理模型数据和存储库,我可以/应该使用通用 QueryBuilder 接口。这种情况适用于我的数据库中不使用数据映射的一些原始数据,我正在寻找一些性能改进。 pages 表在这里仅用于演示概念。
【问题讨论】:
-
我敢打赌,它与在没有给出显式类型的情况下应用默认值有关,以及 sql
LIKE的古怪之处 -
@NikosM。
$stmt->bindValue('title', $title, \PDO::PARAM_STR);也抛出异常,添加case 1A -
我想需要深入研究框架代码才能理解这一点。
-
我想这与作为字段的参数名称存在冲突。可能所有“标题”都替换为
'tablename.title' -
@BerndWilkerπφ 逻辑结论,但仍然不是这个。我添加了带有一些非常独特的参数的案例 1B,仍然是相同的例外。至于其他 1x 案例。
标签: typo3 typo3-10.x doctrine-dbal