Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生成带有可选起始日期和截止日期的SQL where子句_Java_Sql - Fatal编程技术网

Java 生成带有可选起始日期和截止日期的SQL where子句

Java 生成带有可选起始日期和截止日期的SQL where子句,java,sql,Java,Sql,我正在寻找最短的if语句(或其他语句)来构建一个SQL查询,以支持各种情况: 给定“从”日期,没有“到”日期 给定“截止”日期,无“起始”日期 考虑到“从”和“到”日期 没有“从”或“到”日期 缺少“从”或“到”日期表示空值。根据语句的输出,将向类型化查询动态添加一个特定的where子句 如果,我可以用一个嵌套的解决它,但它看起来很难看。有什么建议吗?在创建SQL语句时,您不仅有查询字符串,还有准备好的变量。您将希望同时向这两个对象添加。比如: StringBuilder sql = new S

我正在寻找最短的
if
语句(或其他语句)来构建一个SQL查询,以支持各种情况:

  • 给定“从”日期,没有“到”日期
  • 给定“截止”日期,无“起始”日期
  • 考虑到“从”和“到”日期
  • 没有“从”或“到”日期
  • 缺少“从”或“到”日期表示空值。根据语句的输出,将向类型化查询动态添加一个特定的
    where
    子句


    如果,我可以用一个嵌套的
    解决它,但它看起来很难看。有什么建议吗?

    在创建SQL语句时,您不仅有查询字符串,还有准备好的变量。您将希望同时向这两个对象添加。比如:

    StringBuilder sql = new StringBuilder();
    List<Object> variables = new ArrayList<>();
    
    sql.append("SELECT <columns> FROM <tables> WHERE 1");
    
    if (fromDate != null) {
        sql.append(" AND date >= ?");
        variables.add(fromDate);
    }
    
    if (toDate != null) {
        sql.append(" AND date <= ?");
        variables.add(toDate);
    }
    

    我通常使用StringBuilder构建where子句

    StringBuilder sql = new StringBuilder();
    StringBuilder sqlWhere = new StringBuilder();
    ArrayList<Object> params = new ArrayList<Object>();
    
    if (fromDate != null) {
      sqlWhere.append(" fromDate >= ? ");    
      params.add( fromDate );
    }
    if (toDate != null) {
      sqlWhere.append(" toDate <= ? " + (parms.size() > 0 ? " and " : "") );    
      params.add( toDate );
    }
    
    if ( sqlWhere.size() > 0 ) {
      sql.append(" where ").append( sqlWhere.toString() );
    }
    
    StringBuilder sql=new StringBuilder();
    StringBuilder sqlWhere=新的StringBuilder();
    ArrayList params=新的ArrayList();
    if(fromDate!=null){
    sqlWhere.append(“fromDate>=?”;
    参数添加(起始日期);
    }
    如果(toDate!=null){
    太长了,读不下去了。
    使用Three Ten Extra中的
    LocalDateRange
    类,以及
    StringBuilder::append
    调用中的三元语句

    StringBuilder sql = new StringBuilder();
    sql.append( "SELECT * \n" );
    sql.append( "FROM event_ \n" );
    sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" );  // If the range is unbounded, meaning no beginning AND no ending.
    sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" );  // "not before" is a short way of saying "is equal to or later".
    sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
    sql.append( range.isUnboundedEnd() ? "" : "stop_  < ? \n" );  // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
    sql.append( "; \n" );
    
    这是我们的SQL查询构建代码

    部分
    不开始<?
    是表示“等于或更高”的简短方式。我喜欢这种语法与结尾的另一部分的对称性:“其中x不在开始之前,y在结束之前”

    用开始包含和结束独占来定义时间跨度的逻辑称为半开放。这种方法通常是处理日期-时间最明智的方法。使用这种方法,时间跨度可以整齐地彼此相邻,没有间隙

        StringBuilder sql = new StringBuilder();
        sql.append( "SELECT * \n" );
        sql.append( "FROM event_ \n" );
        sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" );  // If the range is unbounded, meaning no beginning AND no ending.
        sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" );  // "not before" is a short way of saying "is equal to or later".
        sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
        sql.append( range.isUnboundedEnd() ? "" : "stop_  < ? \n" );  // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
        sql.append( "; \n" );
    
    当以开始和结束运行时

    范围=2021-01-23/2021-02-17
    sql=
    选择*
    来自事件(u)
    哪里
    不启动?
    和
    停止?
    ; 
    
    当只从开始运行时

    范围=2021-01-23/+9999999-12-31
    sql=
    选择*
    来自事件(u)
    哪里
    不启动?
    ; 
    
    当只以结尾运行时

    范围=-9999999-01-01/2021-02-17
    sql=
    选择*
    来自事件(u)
    哪里
    停止?
    ; 
    
    当没有开始也没有结束的时候

    范围=-9999999-01-01/+99999999-12-31
    sql=
    选择*
    来自事件(u)
    ; 
    
    你能发布你的代码吗?这样我们就可以看到它看起来有多难看了。@kingdom将澄清作为对你的问题的编辑,而不是评论。如果你正在生成SQL代码,那么就这样说。正如前面所建议的,发布一些代码可能会有所帮助。我必须坚持使用项目库,因此没有jOOQ:(
    for(int index = 1; index <= params.size() : index++) {   
      ps.setObject( index, obj );
    }
    
    StringBuilder sql = new StringBuilder();
    sql.append( "SELECT * \n" );
    sql.append( "FROM event_ \n" );
    sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" );  // If the range is unbounded, meaning no beginning AND no ending.
    sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" );  // "not before" is a short way of saying "is equal to or later".
    sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
    sql.append( range.isUnboundedEnd() ? "" : "stop_  < ? \n" );  // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
    sql.append( "; \n" );
    
        LocalDate start = LocalDate.of( 2021 , Month.JANUARY , 23 );
        LocalDate end = LocalDate.of( 2021 , Month.FEBRUARY , 17 );
        LocalDateRange range = LocalDateRange.of( start , end );           // Both beginning and ending.
        // LocalDateRange range = LocalDateRange.ofUnboundedEnd( start );  // Beginning only.
        // LocalDateRange range = LocalDateRange.ofUnboundedStart( end );  // Ending only.
        // LocalDateRange range = LocalDateRange.ofUnbounded();            // Neither beginning nor ending. 
        Objects.requireNonNull( range );
    
        StringBuilder sql = new StringBuilder();
        sql.append( "SELECT * \n" );
        sql.append( "FROM event_ \n" );
        sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" );  // If the range is unbounded, meaning no beginning AND no ending.
        sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" );  // "not before" is a short way of saying "is equal to or later".
        sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
        sql.append( range.isUnboundedEnd() ? "" : "stop_  < ? \n" );  // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
        sql.append( "; \n" );
    
        System.out.println( "range = " + range );
        System.out.println( "sql = \n" + sql );