准备好的语句在LIKE子句中缺少绑定变量

时间:2017-07-27 15:01:03

标签: java datastax-java-driver cqlsh

我有一个准备好的声明定义为:

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' };

3 个答案:

答案 0 :(得分: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 + "%");

答案 1 :(得分:0)

我认为问题来自你的约束力。如下例所示:http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

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

答案 2 :(得分:0)

上述帖子对于带有绑定变量的简单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只是我为操作日期等而写的一个包。