学说不能返回 json 查询的结果

Posted

技术标签:

【中文标题】学说不能返回 json 查询的结果【英文标题】:Doctrine cant return results on json queries 【发布时间】:2016-06-23 14:08:20 【问题描述】:

可能有标题很接近的线程,但我无法解决这个问题。从 psql 命令行或任何 Postgresql 客户端应用程序调用时,以下查询返回预期结果 但是当我使用 Doctrine 2 实现查询时,我得到以下错误/异常。

raw_data 字段为 JSON 类型。

查询:

    SELECT
      DISTINCT (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER
    FROM schema.projects p
    WHERE p.raw_data :: JSONB ? 'company'
          AND (p.raw_data ->> 'company') :: JSONB ? 'userId'
          AND (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER > 0
          AND p.is_deleted = FALSE
      LIMIT 20;
-- Returns 20 results

教义实施:

public function fetchResulst()

    $sql = "
      SELECT
        DISTINCT (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER
        FROM schema.projects p
        WHERE p.raw_data :: JSONB ? 'company'
            AND (p.raw_data ->> 'company') :: JSONB ? 'userId'
            AND (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER > 0
            AND p.is_deleted = FALSE
          LIMIT 20
      )";

    return $this->_em->getConnection()->executeQuery($sql)->fetchAll();

响应(异常)

Doctrine \ DBAL \ Exception \ SyntaxErrorException
    An exception occurred while executing ' SELECT DISTINCT (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER FROM listing.projects p WHERE p.raw_data :: JSONB ? 'company' AND (p.raw_data ->> 'company') :: JSONB ? 'userId' AND (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER > 0 AND p.is_deleted = FALSE LIMIT 20 ) ': SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "$1" LINE 5: WHERE p.raw_data :: JSONB $1 'company' ^

raw_data 有效载荷中“公司”字段的内容如下。

"company": 
  "CompanyID": 112233445566,
  "URL": null,
  "CompanyName": "Some Real Estate Bla bla Contact Office",
  "PartyNature": "Contact Office",
  "CompanyType": 26,
  "SubNature": null,
  "Description": "",
  "DescriptionLocal": "",
  "ImagePath": null,
  "Phone1": "+90 987 111 11 11",
  "Phone2": "",
  "Fax": null,
  "ContactEmail": "somauser@example.com",
  "NatureID": null,
  "PartySubNatureID": null,
  "CityID": "123",
  "CountyID": "456",
  "DistrictID": "789",
  "id": 14487,
  "userId": 35754

版本Postgresql:PostgreSQL 9.5.2 on x86_64-apple-darwin14.5.0,由 Apple LLVM 版本 7.0.2 (clang-700.1.81) 编译,64 位

学说 - DBAL : v2.5.2

【问题讨论】:

【参考方案1】:

我猜,这与您的数据或字段无关,它与 PDO 及其绑定参数方法有关。如果您不使用? 条件,您可以轻松处理错误。因为教义 dbal 和当然 pdo(在基础中)假设这个 ? 条件运算符作为查询绑定参数,并且将这个绑定参数转换为匹配变量值。卜其实你没有任何价值可以匹配。因为它只是条件运算符。

要处理这个问题,您可以轻松地使用 postgres 的jsonb_exists(column_name, key) 函数。我尝试使用下面的 jsonb_exists 函数创建您示例的正确版本。

    $sql = "
  SELECT
    DISTINCT (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER
    FROM schema.projects p
    WHERE jsonb_exists(p.raw_data :: JSONB, 'company')
        AND jsonb_exists((p.raw_data ->> 'company') :: JSONB, 'userId')
        AND (((p.raw_data ->> 'company') :: JSONB) ->> 'userId') :: INTEGER > 0
        AND p.is_deleted = FALSE
      LIMIT 20
  ";
    $em  = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');

    var_dump($em->getConnection()->executeQuery($sql)->fetchAll()); exit;

我测试过。两个查询都给出相同的结果。

很多数据库库都有这个问题:

https://github.com/tgriesser/knex/issues/519 Yii Postgress Json queries for operator with question marks ?, ?|, ?& Index for finding an element in a JSON array

【讨论】:

以上是关于学说不能返回 json 查询的结果的主要内容,如果未能解决你的问题,请参考以下文章

从查询学说返回字符串

使用连接表返回结果的学说不起作用 Symfony2

php查询sql表中数据,存在则返回显示1,不存在显示0

使用 MSSQL 返回相同孩子的学说

无法查看我使用 json 返回的查询结果

将数据库中查询的结果转换为json, 然后调用接口的方式返回json