Java 发出事先准备好的声明

Java 发出事先准备好的声明,java,mysql,jdbc,Java,Mysql,Jdbc,在以下代码中: PreparedStatement statement = conn .prepareStatement(SQLQueries.isMuted); statement.setString(1, player); statement.setString(2, player); //in SQLQueries.java public static final String isMuted = "SELECT EXISTS

在以下代码中:

PreparedStatement statement = conn
                .prepareStatement(SQLQueries.isMuted);
        statement.setString(1, player);
        statement.setString(2, player);
//in SQLQueries.java
public static final String isMuted = "SELECT EXISTS(SELECT * FROM "
        + "(SELECT playerid FROM mute, players AS player "
        + "WHERE player.username = '?' AND playerid = player.id"
        + "UNION ALL "
        + "SELECT playerid FROM tempmute, players AS player "
        + "WHERE player.username = '?' AND playerid = player.id) AS tbl) "
        + "AS isMuted;";
我得到以下错误:

[08:10:38 WARN]: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
我对此感到非常困惑,因为文档告诉我参数索引从1开始,这已经得到确认,因为当我分别将setString语句更改为0和1时,它给了我另一个错误。另外,该语句有两个占位符,所以我不理解为什么这段代码失败


我是否忽略了文档中的某些内容?

您需要在
player.id
后面留一个空格:

public static final String isBanned = "SELECT EXISTS(SELECT * FROM "
        + "(SELECT playerid FROM bans, players AS player "
        + "WHERE player.username = '?' AND playerid = player.id "
---------------------------------------------------------------^
        + "UNION ALL "
        + "SELECT playerid FROM tempban, players AS player "
        + "WHERE player.username = '?' AND playerid = player.id) AS tbl) "
        + "AS isBanned;";

可能还有其他问题。

删除
PreparedStatement占位符周围的引号。JDBC驱动程序将为您引用字符串。当您自己引用字符串占位符时,JDBC驱动程序认为您希望在语句中传递一个文本


您没有提到您正在使用的数据库,但是MySQL JDBC驱动程序的主要作者在这里确认了这一点:

也许您将参数添加到了
sqlquerys.ismute
而不是
isbanked
?您不应该删除参数周围的引号吗?我认为Keppil是正确的-Java在SQL中没有看到任何参数,它看到(并且不关心)一个条件检查是否与只包含一个问号的文本字符串相等。所以用?更改“?”。我添加了一个空格,但似乎无法修复它。