无法使用 JavaPreparedStatement 在 SQLite 中的日期之间获取结果

问题描述 投票:0回答:1

我一直在尝试使用 Between 语句从具有名为“dia”的日期字段的“produccion”表中获取数据。

我想要的 SQL 语句是:

SELECT * FROM produccion WHERE julianday(dia) BETWEEN julianday('2023-11-01') AND julianday('2023-11-31');

java 代码很难阅读,因为我尝试使代码对所有内容都有效。我已强制启用外键,但我不会超出表范围,所以这应该不重要。

    private ResultSet resultado;
    private PreparedStatement prepSentencia;

    public ResultSet pedirDatos (String[] campos, String tabla, String[][] join, String[] condicionColumna, Object[] condicionValor, String operador, String orden) throws SQLException {

        String select = "SELECT ";
        resultado=null;

        if (campos != null && tabla !=null) {
            for (int x=0; x<campos.length;x++) {
                select = select + campos[x];
                if (x+1<campos.length)
                    select = select + ", ";
            }
            select = select + " FROM "+tabla;
            if (join != null) {
                for (int tupla=0; tupla<join.length; tupla++) {
                    select = select + " INNER JOIN " + join[tupla][0] + " ON "+ tabla + "." + join[tupla][1] + " = " + join[tupla][0] + "." + join[tupla][2];
                }
            }
            // This is the where part
            if (condicionColumna!=null) {
                select = select + " WHERE " ;
                for (int i =0; i<condicionColumna.length;i++) {
                    // Usual where
                    if (condicionColumna[i] != "" && condicionColumna.length==condicionValor.length)
                        select = select + condicionColumna[i]+" = ? ";
                    // Between code goes trough here
                    else if (condicionColumna[i] != "" && condicionColumna.length==1 && condicionValor.length==2)
                        select = select+ condicionColumna[i]+" BETWEEN ? AND ? ";
                    // Verifico si hay más rotaciones y añado el and o el OR
                    if (((i+1)<condicionColumna.length))
                        select = select + " "+operador+" ";
                }
            }

            // Checks for orders
            if (!(orden==null || orden==""))
                select = select + " ORDER BY ? ";
            // Create the sentence
            prepSentencia = conexion.prepareStatement(select+";", PreparedStatement.RETURN_GENERATED_KEYS);
            
            // Fill the data
            if (condicionValor!=null ) {
                for (int i =0; i<condicionValor.length;i++) {
                    if (condicionValor[i] != "")
                        prepSentencia.setObject((i+1),condicionValor[i]);
                    if (((i+1)==condicionValor.length) && !(orden==null || orden==""))
                        prepSentencia.setString(i+2,orden);
                }
            } else if (!(orden==null || orden==""))
                prepSentencia.setString(1,orden);
            resultado = prepSentencia.executeQuery();
        }
        else
            throw new SQLException ("I need input data");
        return resultado;
    }

数据输入:

pedirDatos(new String[] {"*"}, "produccion",null,new String[] {"julianday(dia)"},new String[] {"julianday('2023-11-01')","julianday('2023-11-31')"},"AND",null); 

该表之前已形成,语句如下:

regularstatement.execute("CREATE TABLE IF NOT EXISTS produccion(\n"
        + " id_produccion INTEGER PRIMARY KEY,\n"
        + " dia TEXT NOT NULL,\n"
        + " hora TEXT NOT NULL,\n"
        + " cantidad REAL NOT NULL,\n"
        + " num_animales INTEGER NOT NULL,\n"
        + " media_por_animal INTEGER,\n"
        + " incidencias TEXT \n"
        + ");");

我知道 SQLite 中有日期字段,所以我将其设为文本。

我正在调试,发现程序正确地执行了所有代码,并且调试结果集包含带有以下信息的 stmt 部分:

从生产中选择*,其中 julianday(dia) 之间?和 ? ; 参数=[julianday('2023-11-01'), julianday('2023-11-31')]

我已验证表中有两行日期为 2023-11-17

所以看来我在准备好的语句中正确地注入了数据,并且我觉得这句话是正确的。我不知道为什么我没有得到结果,因为我在程序的其余部分中已经成功地使用了它。

我还尝试使用 julianday(data,'utc')、strftime()、date() 并直接使用日期。我查看了 https://sqlite.org/lang_datefunc.html 但无法使其工作。

让我丧命的是,使用在线查看器(https://inloop.github.io/sqlite-viewer/)我可以使 SQL 工作,但是当运行 java 时,它应该不返回任何数据。

编辑:澄清一下,当我尝试

SELECT * FROM 'produccion' WHERE dia BETWEEN '2023-11-01' AND '2023-11-30'
但没有成功时,我开始遇到这个问题。后来在 putString 中使用 julianday 时犯了一个错误,但问题仍然存在,因为常规 SQL 语句应该可以工作。

java sqlite prepared-statement between
1个回答
0
投票

查询中的

?
占位符将替换为参数
julianday('2023-11-01')
julianday('2023-11-31')
,如下所示:

SELECT * FROM produccion 
WHERE julianday(dia) BETWEEN 'julianday('2023-11-01')' AND 'julianday('2023-11-31')';

(单引号正确转义)因为您将它们作为字符串传递。

您应该编写查询:

SELECT * FROM produccion 
WHERE julianday(dia) BETWEEN julianday(?) AND julianday(?);

并传递参数

'2023-11-01'
'2023-11-30'
(不是
'2023-11-31'
,因为 11 月只有 30 天)。

但是,为什么在查询中使用

julianday()

如果您的日期格式正确为
YYYY-MM-DD
,那么编写这样的查询会更简单:

SELECT * FROM produccion 
WHERE dia BETWEEN ? AND ?;
© www.soinside.com 2019 - 2024. All rights reserved.