从PHP查询时,视图中的Postgresql regexp_matches始终返回null

时间:2016-12-08 00:39:44

标签: php regex postgresql base64

我的观点类似于这个

CREATE OR REPLACE VIEW regexp_test AS (
    SELECT regexp_matches(decode('NTB4', 'base64')::text, '(\d+)x')
)

当我从pgAdmin查询视图时,按预期返回单值为50的数组。

SELECT * FROM regexp_test

但是当我通过pg_query('SELECT * FROM regexp_test')在PHP中调用相同的查询时,不会返回任何内容。

postgres版本9.5.3, php版本7.0.3(与5.6.14相同的结果)

PHP代码很简单:

<?php

$link = pg_connect('host=localhost port=5432 dbname=test user=postgres password=postgres');
$qry = "SELECT * FROM regexp_test";
$res = pg_query($link, $qry);

while ($row = pg_fetch_row($res)) {
    print_r($row);
}

3 个答案:

答案 0 :(得分:1)

相同的查询

select  e'\\x353078'::bytea;

psql

中提供不同格式的结果
  bytea
----------
 \x353078

并在 PgAdmin III

  bytea
----------
 50x

For the documentation:

  

bytea类型支持两种输入和输出的外部格式:PostgreSQL的历史&#34;转义&#34;格式和&#34; hex&#34;格式。输入时始终接受这两个。输出格式取决于配置参数bytea_output;默认值为十六进制。 (注意,在PostgreSQL 9.0中引入了十六进制格式;早期版本和一些工具不了解它。)

PgAdmin III(以及PgAdmin4)可能由于历史原因将bytea_output的值设置为escape,而参数的默认值为hex。这可能会导致混淆(正如您所看到的那样)。似乎pgAdmin不应该更改参数的默认值。

您可以更改应用程序中的参数以获得与PgAdmin相同的行为:

set bytea_output to escape;

当然,使用encode()也是一个很好的解决方案。

答案 1 :(得分:0)

pg_query返回结果资源。

$result = pg_query('SELECT * FROM regexp_test');

while ($row = pg_fetch_row($result)) {
  echo "$row";
}

pg_query returns false on error

  

如果发生错误,并且返回FALSE,如果连接有效,则可以使用pg_last_error()函数检索错误的详细信息。

答案 2 :(得分:0)

我发现使用encode(decode('NTB4', 'base64'), 'escape')而不是类型decode('NTB4', 'base64')::text修复问题。

所以测试视图现在看起来像这样:

CREATE OR REPLACE VIEW regexp_test AS (
    SELECT regexp_matches(encode(decode('NTB4', 'base64'), 'escape'), '(\d+)x')
)

现在调用pg_query('SELECT * FROM regexp_test')会返回预期结果 - 其中包含'{50}'的单行/字段。