Java prepareStatement()似乎是分号

Java prepareStatement()似乎是分号,java,prepared-statement,Java,Prepared Statement,我正在尝试使用以下命令执行准备好的语句: dbaBean.setPrepStmt(dbaBean.getConn().prepareStatement( "SELECT id, author, title, url, article_text, date_created " + "FROM articles WHERE " + "(EXTRACT(YEAR FROM date_created) = ? OR ? is null) " +

我正在尝试使用以下命令执行准备好的语句:

dbaBean.setPrepStmt(dbaBean.getConn().prepareStatement(
    "SELECT id, author, title, url, article_text, date_created " +
            "FROM articles WHERE " +
            "(EXTRACT(YEAR FROM date_created) = ? OR ? is null) " +
            "AND (EXTRACT(MONTH FROM date_created) = ? OR ? is null) " +
            "AND (EXTRACT(DAY FROM date_created) = ? OR ? is null) AND " +
            "(url = ? OR ? is null) " +
            "ORDER BY date_created DESC;"));

dbaBean.getPrepStmt().setString(1, year);
dbaBean.getPrepStmt().setString(2, year);
dbaBean.getPrepStmt().setString(3, month);
dbaBean.getPrepStmt().setString(4, month);
dbaBean.getPrepStmt().setString(5, day);
dbaBean.getPrepStmt().setString(6, day);
dbaBean.getPrepStmt().setString(7, URL);
dbaBean.getPrepStmt().setString(8, URL);

System.out.println(dbaBean.getPrepStmt().toString());
dbaBean是一个提供连接和准备状态的对象。它根本不做任何操作

我已经成功地将上述代码用于其他方法,并且没有遇到任何问题。现在,此函数似乎正在剥离末尾的分号,例如,这是与System.out行一起输出的:

SELECT id, author, title, url, article_text, date_created FROM articles WHERE (EXTRACT(YEAR FROM date_created) = NULL OR NULL is null) AND (EXTRACT(MONTH FROM date_created) = NULL OR NULL is null) AND (EXTRACT(DAY FROM date_created) = NULL OR NULL is null) AND (url = 'someurl' OR 'someurl' is null) ORDER BY date_created desc
请注意缺少的分号

我尝试添加第二个分号,它也被“吃掉”

其他更改也会进行,例如选择另一个字段

如果这很重要的话,这就是postgresql

编辑:我关心这个问题,因为我在运行这个查询时遇到了一个错误,我认为删除分号是潜在的罪魁祸首。下面的答案似乎表明情况并非如此,我需要在别处寻找它。

preparedStatementString sql方法获取输入字符串并创建一个CallableStatement对象来调用数据库存储过程

在初始化CallableStatement对象期间,jdbc驱动程序将sql字符串转换为系统的本机sql语法


由于分号是Postgresql的分隔符,您可以假定它已被jdbc驱动程序删除,如果使用其他jdbc驱动程序实现,则可能会有所不同。因此,最好的办法是将其从SQL字符串中删除。

我花了几分钟的时间浏览了Postgresql JDBC驱动程序的源代码,结果似乎如下所示:

当创建准备好的语句时,驱动程序会进行部分解析,将SQL拆分为语句,查找占位符,我想删除任何注释

解析的结果存储在PreparedStatement对象中一系列片段

如果在语句上调用toString,该方法将重建SQL,为占位符插入值,并在每个语句之间添加分号。。。如果有多个语句


因此,消失的分号是一个特性,而不是一个bug。JDBC规范中的任何内容都不要求toString方法以其原始形式提供查询。。。或者以任何形式。此外,在为JDBC编写SQL时,至少Postgresql会在后面省去分号,这是一种正常的做法。

为什么您会在意?分号不是SQL语句的一部分,它更像是一个分隔符,如果只发出一条语句,则不需要它。只要语句执行良好,分号就无所谓。我同意前面的评论。分号不是SQL语句的一部分-DBMS接口使用它来指示SQL命令已完成并准备好执行。如果只按ENTER键,它将理解您正在键入多行命令。因此,准备好的语句可能是去掉了终止符,以便只保留真正的语句。