【问题标题】:Cant create table with preparedStatement无法使用preparedStatement 创建表
【发布时间】:2016-02-10 09:54:42
【问题描述】:

我无法在数据库 (mySQL) 中创建表,使用 preparedStatement 并尝试使用 preparedStatement.setInteger() 输入未来表的名称:

static String queryCreateTable = "CREATE TABLE ?" +
                                 "(ID INTEGER not NULL ," +
                                 "BRAND VARCHAR(40)," +
                                 "MODEL VARCHAR(40)," +
                                 "YEAR INTEGER not NULL," +
                                 "NOVELTY BINARY," +
                                 "PRIMARY KEY ( ID ))";

然后我尝试在用户输入表名后构造和调用语句:

newNameOfTable = JOptionPane.showInputDialog("Connected for saving data. " +
                                "Input name of new table:");

                        pStatement = connection.prepareStatement(queryCreateTable);
                        pStatement.setString(1, newNameOfTable);
                        pStatement.executeUpdate();

如果我尝试在不输入名称的情况下执行它,效果很好(比如常量字符串:“CREATE TABLE newtable (...)”但我需要输入名称..

【问题讨论】:

标签: java mysql sql


【解决方案1】:

您必须在读取表名后格式化字符串,例如:

static String queryCreateTable = "CREATE TABLE {0}" +
                                 "(ID INTEGER not NULL ," +
                                 "BRAND VARCHAR(40)," +
                                 "MODEL VARCHAR(40)," +
                                 "YEAR INTEGER not NULL," +
                                 "NOVELTY BINARY," +
                                 "PRIMARY KEY ( ID ))";

然后像这样创建:

newNameOfTable = JOptionPane.showInputDialog("Connected for saving data. " +
                            "Input name of new table:");

statement = connection.createStatement();
statement.execute(MessageFormat.format(queryCreateTable, newNameOfTable));

【讨论】:

    【解决方案2】:
    newNameOfTable = JOptionPane.showInputDialog("Connected for saving data. " +
                                    "Input name of new table:");
    
    static String queryCreateTable = "CREATE TABLE " + newNameOfTable +
                                     "(ID INTEGER not NULL ," +
                                     "BRAND VARCHAR(40)," +
                                     "MODEL VARCHAR(40)," +
                                     "YEAR INTEGER not NULL," +
                                     "NOVELTY BINARY," +
                                     "PRIMARY KEY ( ID ))";
    
    
    pStatement = connection.prepareStatement(queryCreateTable);
    pStatement.executeUpdate();
    

    PreparedStatement 示例: http://tutorials.jenkov.com/jdbc/preparedstatement.html

    【讨论】:

    • 这并不能解决 OP 遇到的问题。他想使用 PreparedStatement 来防止 MySQL 注入攻击。通过简单地将表的名称作为文本附加到命令中,攻击者可以以允许他运行不应被允许运行的命令的方式输入一些内容。例如,查询其他用户的数据或上帝禁止删除表或删除整个数据库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 2020-11-04
    • 2020-04-20
    相关资源
    最近更新 更多