查询中的问号运算符

时间:2015-04-29 13:07:17

标签: php postgresql laravel laravel-5

在我的laravel 5应用程序中,我使用的是PostgreSQL的jsonb数据类型,它有?运算符。

但是我无法在我的模型中使用它,因为laravel使用问号作为绑定。

具体来说,在whereRaw()方法中:

$query->whereRaw("jsonb_column ? 'a_key'")

如何在查询中使用问号?

3 个答案:

答案 0 :(得分:4)

您可以考虑使用函数调用而不是运算符。

首先你应该找出哪个功能?运算符通过PostgresSQL数据库上的以下查询使用:

SELECT oprname, oprcode FROM pg_operator WHERE oprname = '?'

在我的开发数据库中它的 jsonb_exists 功能, 然后您可以将查询更新为:

$query->whereRaw("jsonb_exists(jsonb_column, 'a_key')")

我希望它有所帮助,快乐编码。

答案 1 :(得分:3)

基本上你有两个选择:

  1. 通过扩展Laravel的查询生成器实现whereRaw的当前方式来解决问题,否则做得很难
  2. 向Laravel团队发送功能请求(即要求他们扩展处理更多PostgresQL细节的所有Query Builder组件)并且如果您耐心,他们会交叉说明。
  3. 以下是我对[1.]选项的看法:

    名称空间“Illuminate \ Database \ Query”对您有好处:

    您需要特别深入研究以下Laravel 5.0源代码:

    感兴趣的代码片段:

    Builder.php中的

    whereRaw(摘录):

    /**
     * Add a raw where clause to the query.
     *
     * @param  string  $sql
     * @param  array   $bindings
     * @param  string  $boolean
     * @return $this
     */
    public function whereRaw($sql, array $bindings = array(), $boolean = 'and')
    {
        $type = 'raw';
        $this->wheres[] = compact('type', 'sql', 'boolean');
        $this->addBinding($bindings, 'where');
        return $this;
    }
    
    Grammar.php中的

    compileWheres(摘录):

    /**
     * Compile the "where" portions of the query.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @return string
     */
    protected function compileWheres(Builder $query)
    {
        $sql = array();
        if (is_null($query->wheres)) return '';
        // Each type of where clauses has its own compiler function which is responsible
        // for actually creating the where clauses SQL. This helps keep the code nice
        // and maintainable since each clause has a very small method that it uses.
        foreach ($query->wheres as $where)
        {
            $method = "where{$where['type']}";
            $sql[] = $where['boolean'].' '.$this->$method($query, $where);
        }
        // If we actually have some where clauses, we will strip off the first boolean
        // operator, which is added by the query builders for convenience so we can
        // avoid checking for the first clauses in each of the compilers methods.
        if (count($sql) > 0)
        {
            $sql = implode(' ', $sql);
            return 'where '.$this->removeLeadingBoolean($sql);
        }
        return '';
    }
    
    PostgresGrammar.php中的

    $operators array(摘录):

    /**
     * All of the available clause operators.
     *
     * @var array
     */
    protected $operators = array(
        '=', '<', '>', '<=', '>=', '<>', '!=',
        'like', 'not like', 'between', 'ilike',
        '&', '|', '#', '<<', '>>',
    );
    

    请注意?不是有效运算符; - )

    PostgresGrammar.php中的

    Specialized PostgreSQL protected methods(摘录):

    /**
     * Compile the additional where clauses for updates with joins.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @return string
     */
    protected function compileUpdateWheres(Builder $query)
    {
        $baseWhere = $this->compileWheres($query);
        if ( ! isset($query->joins)) return $baseWhere;
        // Once we compile the join constraints, we will either use them as the where
        // clause or append them to the existing base where clauses. If we need to
        // strip the leading boolean we will do so when using as the only where.
        $joinWhere = $this->compileUpdateJoinWheres($query);
        if (trim($baseWhere) == '')
        {
            return 'where '.$this->removeLeadingBoolean($joinWhere);
        }
        return $baseWhere.' '.$joinWhere;
    }
    /**
     * Compile the "join" clauses for an update.
     *
     * @param  \Illuminate\Database\Query\Builder  $query
     * @return string
     */
    protected function compileUpdateJoinWheres(Builder $query)
    {
        $joinWheres = array();
        // Here we will just loop through all of the join constraints and compile them
        // all out then implode them. This should give us "where" like syntax after
        // everything has been built and then we will join it to the real wheres.
        foreach ($query->joins as $join)
        {
            foreach ($join->clauses as $clause)
            {
                $joinWheres[] = $this->compileJoinConstraint($clause);
            }
        }
        return implode(' ', $joinWheres);
    }
    

    将这些视为上面提到的compileWheres的一种特殊化,除了两个(仅2个!!!)特定的情况之外的其余情况是使用父类方法编译的(Illuminate \ Database \ Query \语法\语法)。

    其他推荐的相关资源

    您可以在此博客中找到有价值的信息(SOFTonSOFA)。

    我特别推荐:

    最后但并非最不重要的是,Laravel documentation是了解其建筑基础(服务提供商,服务容器,外墙等)的最佳地点。掌握它可以方便地设计框架的强大扩展

    希望我的输入为您提供的Laravel Query Builder可能的扩展点提供了足够的提示,并且它可以作为一个很好的起点,让您编写解决?运算符问题的PostgreSQL扩展{{1} }}

    完成后请回馈/分享。

答案 2 :(得分:-2)

尝试使用反斜杠转义,例如

SELECT * FROM table WHERE id = \?;