Postgresql SQLSTATE [42P18]:具有 PDO 和 CONCAT 的不确定数据类型
Postgresql SQLSTATE[42P18]: Indeterminate datatype with PDO and CONCAT
CONCAT()
在 WHERE
、PDO
中使用时遇到问题。
代码:
<?php
require_once('config.php');
$fdate = '01/01/2010';
$tdate = '31/12/2030';
$identification = '';
$count = "SELECT count(*) as total FROM ( select time_id from doc_sent WHERE date >= :fdate AND date <= :tdate AND identification LIKE concat('%',:identification,'%') ) x;";
//$count = "SELECT count(*) as total FROM ( select time_id from doc_sent WHERE date >= :fdate AND date <= :tdate ) x;";
$stmt_count_row_main_table = $pdo->prepare($count);
$stmt_count_row_main_table->execute(['fdate' => $fdate, 'tdate' => $tdate, 'identification' => $identification]);
//$stmt_count_row_main_table->execute(['fdate' => $fdate, 'tdate' => $tdate]);
$count_row_main_table = $stmt_count_row_main_table->fetch();
print_r( $count_row_main_table);
?>
注释 'identification' 部分时代码有效。
当我尝试使用 CONCAT() 时,它没有。
我尝试了很多 "version" 的 CONCAT() (并阅读了许多其他问题,比如这个:How do I create a PDO parameterized query with a LIKE statement?)但我总是指的是主要文档:
https://www.postgresql.org/docs/9.1/static/functions-string.html
其中说:
concat('abcde', 2, NULL, 22) --> abcde222
我使用 CONCAT() 时的完整错误是:
PHP Fatal error: Uncaught PDOException: SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter in /var/www/pdo-reporter/show.php:17\nStack trace:\n#0 /var/www/pdo-reporter/show.php(17): PDOStatement->execute(Array)\n#1 {main}\n thrown in /var/www/pdo-reporter/show.php on line 17
我的代码有什么问题?
CONCAT
是一个接受 VARIADIC 参数列表的函数,这意味着在内部 postgres 会将它们转换为相同类型的数组。
postgres=# \df concat
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------+------------------+---------------------+------
pg_catalog | concat | text | VARIADIC "any" | func
尝试将输入类型解析为单一类型时,SQL 解析器失败。它可以以这种更简单的形式复制:
postgres=# PREPARE p AS select concat('A', );
ERROR: could not determine data type of parameter
解析器无法确定 </code> 的数据类型,因此谨慎行事。</p>
<p>一个简单的解决方案是将参数转换为文本:</p>
<pre><code>postgres=# PREPARE p AS select concat(::text);
PREPARE
或使用 CAST 运算符:
postgres=# PREPARE p AS select concat(cast( as text));
PREPARE
我没有使用 PDO 进行测试,但大概可以将查询更改为:
(考虑到它如何处理参数以生成准备好的语句)
"...identification LIKE '%' || :identification || '::text%'..."
或者使用'||'运算符而不是查询中的 concat
:
identification LIKE '%' || :identification || '%'
编辑:顺便说一句,如果你想找到参数 :X
是 identification
的子串,这个子句更安全:strpos(identification, :X) > 0
,因为 :X
可能包含 '%' 或 '_' 而不会在匹配中引起任何 side-effect,这与 LIKE
.
的情况相反
CONCAT()
在 WHERE
、PDO
中使用时遇到问题。
代码:
<?php
require_once('config.php');
$fdate = '01/01/2010';
$tdate = '31/12/2030';
$identification = '';
$count = "SELECT count(*) as total FROM ( select time_id from doc_sent WHERE date >= :fdate AND date <= :tdate AND identification LIKE concat('%',:identification,'%') ) x;";
//$count = "SELECT count(*) as total FROM ( select time_id from doc_sent WHERE date >= :fdate AND date <= :tdate ) x;";
$stmt_count_row_main_table = $pdo->prepare($count);
$stmt_count_row_main_table->execute(['fdate' => $fdate, 'tdate' => $tdate, 'identification' => $identification]);
//$stmt_count_row_main_table->execute(['fdate' => $fdate, 'tdate' => $tdate]);
$count_row_main_table = $stmt_count_row_main_table->fetch();
print_r( $count_row_main_table);
?>
注释 'identification' 部分时代码有效。 当我尝试使用 CONCAT() 时,它没有。
我尝试了很多 "version" 的 CONCAT() (并阅读了许多其他问题,比如这个:How do I create a PDO parameterized query with a LIKE statement?)但我总是指的是主要文档: https://www.postgresql.org/docs/9.1/static/functions-string.html
其中说:
concat('abcde', 2, NULL, 22) --> abcde222
我使用 CONCAT() 时的完整错误是:
PHP Fatal error: Uncaught PDOException: SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter in /var/www/pdo-reporter/show.php:17\nStack trace:\n#0 /var/www/pdo-reporter/show.php(17): PDOStatement->execute(Array)\n#1 {main}\n thrown in /var/www/pdo-reporter/show.php on line 17
我的代码有什么问题?
CONCAT
是一个接受 VARIADIC 参数列表的函数,这意味着在内部 postgres 会将它们转换为相同类型的数组。
postgres=# \df concat
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------+------------------+---------------------+------
pg_catalog | concat | text | VARIADIC "any" | func
尝试将输入类型解析为单一类型时,SQL 解析器失败。它可以以这种更简单的形式复制:
postgres=# PREPARE p AS select concat('A', );
ERROR: could not determine data type of parameter
解析器无法确定 </code> 的数据类型,因此谨慎行事。</p>
<p>一个简单的解决方案是将参数转换为文本:</p>
<pre><code>postgres=# PREPARE p AS select concat(::text);
PREPARE
或使用 CAST 运算符:
postgres=# PREPARE p AS select concat(cast( as text));
PREPARE
我没有使用 PDO 进行测试,但大概可以将查询更改为:
(考虑到它如何处理参数以生成准备好的语句)"...identification LIKE '%' || :identification || '::text%'..."
或者使用'||'运算符而不是查询中的 concat
:
identification LIKE '%' || :identification || '%'
编辑:顺便说一句,如果你想找到参数 :X
是 identification
的子串,这个子句更安全:strpos(identification, :X) > 0
,因为 :X
可能包含 '%' 或 '_' 而不会在匹配中引起任何 side-effect,这与 LIKE
.