【问题标题】:prepared statement missing bind variable within a LIKE clause准备好的语句在 LIKE 子句中缺少绑定变量
【发布时间】:2018-01-03 09:39:28
【问题描述】:

我有一个准备好的语句定义为:

selectLikeShortnameStmt = cassandraDatasource.getSession().prepare(" select  id,
     parent_id, ultimate_parent_id, internal_ref, short_name,
     long_name, controlling_team from counterparty where short_name like'%?%'");

但是当我尝试在 DAO 中使用它时:

PreparedStatement pStmt = statementFactory.getSelectLikeShortnameStmt();
BoundStatement bStmt = pStmt.bind( short_name );

我收到一条错误消息,提示 Prepared 语句没有绑定变量。 为了实现 like 子句,我使用了 SASI 索引功能,即:

CREATE CUSTOM INDEX short_name_like_index ON counterparty (short_name)
USING 'org.apache.cassandra.index.sasi.SASIIndex'
WITH OPTIONS = { 'mode': 'CONTAINS' };

【问题讨论】:

  • 点赞后加空格并以:?开头

标签: java datastax-java-driver cqlsh


【解决方案1】:

这不起作用,因为'%?%' 中使用的? 是字符串的一部分,它不是它自己的绑定变量,您需要执行以下操作:

selectLikeShortnameStmt = cassandraDatasource.getSession().prepare("select id, parent_id, ultimate_parent_id, internal_ref, short_name, long_name, controlling_team from counterparty where short_name like ?");
PreparedStatement pStmt = statementFactory.getSelectLikeShortnameStmt();
BoundStatement bStmt = pStmt.bind("%" + short_name + "%");

【讨论】:

    【解决方案2】:

    我认为问题出在您的绑定上。如这里的示例:http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

    您可能想要执行以下操作:pStmt.setString(short_name);

    【讨论】:

    • 嗨,我试过了:从短名称类似 '%:?%'" 的交易对手那里得到同样的问题
    • 改变了我的答案。
    【解决方案3】:

    上面的帖子对于带有绑定变量的直接 PreparedStatement 效果很好,但我遇到了另一个类似的问题。我正在使用 Apache Lucerne 索引构建器进行更复杂的查询,即。具有如下索引定义的范围:

    CREATE CUSTOM INDEX counterparty_column_index ON counterparty (filter_column)
    USING 'com.stratio.cassandra.lucene.Index'
    WITH OPTIONS = {
        'schema' : '{
            fields : {
            controlling_team     : {type : "text", analyzer : "english"},
            relationship_manager : {type : "text", analyzer : "english"},
            review_date          : {type : "date", pattern : "dd-MM-yyyy"}
            }
        }'
    };
    

    而语句定义为:

        log.info("CounterpartyStatement [selectByReviewDateAndTeamStmt]");
        selectByReviewDateAndTeamStmt       =  cassandraDatasource.getSession().prepare(" select  id, parent_id, ultimate_parent_id, internal_ref, short_name, long_name, controlling_team, " +
                                                " country_incorp, country_operate, company_reg, relationship_manager, credit_rating, rating_source, pd, lgd, review_date, sector, defaulted, own_bank_entity " +
                                                " from counterparty where filter_column = '{ " 
                                                             + " filter : {type:\"range\", field:\"review_date\", lower:\"01-01-2000\", upper:\"%s\"},"
                                                             + " query : {type:\"contains\", field:\"controlling_team\", values:[\"%s\"]},"
                                                             + " refresh:true"
                                                             + " }'");   
    

    这种格式是必要的,因为标准 PreparedStatement 绑定没有采用通常的方式?占位符。

    然后代码变成了:

    log.info("CounterpartyDAO.getRmCounterpartiesForReview [" + rm + "]");
        PreparedStatement pStmt = statementFactory.getSelectByReviewDateAndRmStmt();
    
        String query = pStmt.getQueryString();
        Date maxDate = dateUtils.addDays( dateUtils.getToday(), 3);
        String maxDateString = dateUtils.getAnyDate(maxDate, "dd-MM-yyyy");
        query = String.format( query, maxDateString, rm );
    
        ResultSet rs = cassandraDatasource.getSession().execute( query );
    

    这也很好用,dateUtils 只是我为操作日期等而编写的一个包。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 2019-07-02
      • 1970-01-01
      • 2019-11-09
      相关资源
      最近更新 更多