查询 1。
我尝试使用 PHP 运行它:
<?php
$pdo = new \PDO('pgsql:host=localhost;dbname=postgres', 'postgres', 'postgres');
$sql = <<<SQL
SELECT *
FROM (
SELECT 'CHAC TECHNOLOG*' as alias
UNION
SELECT 'KINDERY LIGHTING SALES DE?T*'
) m
JOIN (
SELECT 'CHACTECHNOLOGICO\\' as ie_clean
UNION
SELECT 'KINDERYLIGHTINGSALESDEPT' as ie_clean
) t ON t.ie_clean ILIKE REPLACE(REPLACE(REPLACE(m.alias, '*', '%'), '?', '_'), ' ', '')
ORDER BY ie_clean;
SQL;
echo $sql . PHP_EOL . PHP_EOL;
$stmt = $pdo->query($sql);
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
我有下一个输出:
SELECT *
FROM (
SELECT 'CHAC TECHNOLOG*' as alias
UNION
SELECT 'KINDERY LIGHTING SALES DE?T*'
) m
JOIN (
SELECT 'CHACTECHNOLOGICO\' as ie_clean
UNION
SELECT 'KINDERYLIGHTINGSALESDEPT' as ie_clean
) t ON t.ie_clean ILIKE REPLACE(REPLACE(REPLACE(m.alias, '*', '%'), '?', '_'), ' ', '')
ORDER BY ie_clean;
Array
(
[0] => Array
(
[alias] => CHAC TECHNOLOG*
[ie_clean] => CHACTECHNOLOGICO\
)
)
只有一个记录(这是错误的)。
但是当我尝试直接在 PostgreSQL 中运行它时,此查询返回两条记录。这是正确的结果。
https://www.db-fiddle.com/f/qNZY5SauB87na2pWf8uwxm/0
查询 2。
这是类似的查询,但现在我将部分条件从
WHERE
移动到 SELECT
部分:<?php
$pdo = new \PDO('pgsql:host=localhost;dbname=postgres', 'postgres', 'postgres');
$sql = <<<SQL
SELECT *
FROM (
SELECT REPLACE(REPLACE(REPLACE('CHAC TECHNOLOG*', '*', '%'), '?', '_'), ' ', '') as alias
UNION
SELECT REPLACE(REPLACE(REPLACE('KINDERY LIGHTING SALES DE?T*', '*', '%'), '?', '_'), ' ', '')
) m
JOIN (
SELECT 'CHACTECHNOLOGICO\\' as ie_clean
UNION
SELECT 'KINDERYLIGHTINGSALESDEPT' as ie_clean
) t ON t.ie_clean ILIKE m.alias
ORDER BY ie_clean;
SQL;
echo $sql . PHP_EOL . PHP_EOL;
$stmt = $pdo->query($sql);
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
输出是:
SELECT *
FROM (
SELECT REPLACE(REPLACE(REPLACE('CHAC TECHNOLOG*', '*', '%'), '?', '_'), ' ', '') as alias
UNION
SELECT REPLACE(REPLACE(REPLACE('KINDERY LIGHTING SALES DE?T*', '*', '%'), '?', '_'), ' ', '')
) m
JOIN (
SELECT 'CHACTECHNOLOGICO\' as ie_clean
UNION
SELECT 'KINDERYLIGHTINGSALESDEPT' as ie_clean
) t ON t.ie_clean ILIKE m.alias
ORDER BY ie_clean;
Array
(
[0] => Array
(
[alias] => CHACTECHNOLOG%
[ie_clean] => CHACTECHNOLOGICO\
)
[1] => Array
(
[alias] => KINDERYLIGHTINGSALESDE_T%
[ie_clean] => KINDERYLIGHTINGSALESDEPT
)
)
两个记录!这是正确的结果。
Postgres 也返回两条记录(这是正确的):
https://www.db-fiddle.com/f/nSv1Tg9YJMgfUUhn7urFyF/0
问题
我认为问题出在
'CHACTECHNOLOGICO\\'
中的尾部斜线,但我重新检查了它,我认为它是正确的。为什么查询 1 只从 PHP 返回一条记录。是 PDO 的错误还是我做错了什么?
UPD
https://bugs.php.net/bug.php?id=78534
最佳答案
问题的根源是 REPLACE 函数之一内的问号。
到达服务器的实际查询看起来像
SELECT *
FROM (
SELECT 'CHAC TECHNOLOG*' as alias
UNION
SELECT 'KINDERY LIGHTING SALES DE?T*'
) m
JOIN (
SELECT 'CHACTECHNOLOGICO\' as ie_clean
UNION
SELECT 'KINDERYLIGHTINGSALESDEPT' as ie_clean
) t ON t.ie_clean ILIKE REPLACE(REPLACE(REPLACE(m.alias, '*', '%'), '$1', '_'), ' ', '')
ORDER BY ie_clean;
所以 PDO 取代了 ? 到 $1 和查询的第二部分变得无效,导致 1 行
您必须以某种方式绑定(bind)该值(这很棘手并且可能不起作用)或更改您的查询使用 ?。
试试这个看看实际结果(不推荐,这里有很多关于这个选项的讨论)
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
关于php - 通过 PDO 执行的查询返回的记录比从 PostgreSQL 少,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57858915/