Java 将表名作为已准备语句的参数传递
我正在尝试学习如何将MySQL与Java结合使用,正如标题所说,我在准备语句时遇到了问题 我有一个名为temp的MySQL表,其中包含值(直接从MySQL控制台输出): 在Java中,我访问数据库的方式如下:Java 将表名作为已准备语句的参数传递,java,mysql,sql,prepared-statement,Java,Mysql,Sql,Prepared Statement,我正在尝试学习如何将MySQL与Java结合使用,正如标题所说,我在准备语句时遇到了问题 我有一个名为temp的MySQL表,其中包含值(直接从MySQL控制台输出): 在Java中,我访问数据库的方式如下: stmt = conn.prepareStatment("select * from ?"); stmt.setString(1,"temp"); ResultSet rs = stmt.executeQuery(); //This method call throws the excep
stmt = conn.prepareStatment("select * from ?");
stmt.setString(1,"temp");
ResultSet rs = stmt.executeQuery(); //This method call throws the exception
stmt.toString
显示:select*from'temp'
异常消息是:您的SQL语法有错误;检查与MySQL服务器版本对应的手册,以了解第1行“temp”附近使用的正确语法
当我直接在MySQL控制台中键入select*from'temp'
(stmt.toString()的输出)时,我得到了完全相同的消息
正如您可能想象的那样,我计划将这个概念应用到JSP网页,其中表名将是一个HTTPGET参数。所以我的问题是:如何将表名绑定到准备好的语句,如果不可能(这是我从PHP的类似问题中得到的感觉),我将如何清理表名的输入?您不能这样做。您需要使用字符串连接构造sql
PreparedStatement
用于列值而不是表名。您不能对表名使用stmt.setString()
或setInt()
函数,它仅对列值有效。这种要求指出了数据库设计中的缺陷。如果“subject”表包含不同的信息,如何使用相同的查询检索该信息
您正在从表中选择所有列,并使应用程序对它需要和不需要的内容进行排序。这会在应用程序中产生风险和漏洞,在通信通道上产生冗余数据传输,并且在应用程序流行时难以进行数据库优化。我怀疑您的应用程序代码是一个由if和case组成的复杂程序,用于整理返回的列。如果您对代码进行合理化,使每个表格式都由特定的类知道和处理,那么您的代码将更加简单,并且您的表名不再必须是参数
替换表名也会由于创建SQL注入漏洞而产生无法克服的安全问题。如果有人给你(fish-INNER-JOIN-mysql.user-ON-TRUE)
作为表名会怎么样。与您的all column select一起,将为他们提供MySQL用户表!你想要吗??转义表值对您毫无帮助。事实上,它只会给攻击者提供更大范围的字符,他们可以将这些字符注入到SQL语句中
您需要做的是将数据库设计合理化并规范化为一个表,该表有一个“主题”列,您可以使用准备好的语句参数进行选择。是的,我看到了,但答案对这一点不是很有信心,也不是很有帮助。为了将来遇到这个问题的每个人,我希望找到一个更好的答案或解决方案,这不会牺牲安全性。你不需要净化表名(与表单数据不同),所以我不认为这是一个问题。我正在尝试用多个卡片主题制作一个flashcard程序,所以我希望每个主题都是一个不同的表(不同的主题可能需要存储不同的信息)。这仍然不需要使用预先准备好的语句。你只需要看着它完成,不!永远不要使用外部提供的值作为表名!
stmt = conn.prepareStatment("select * from ?");
stmt.setString(1,"temp");
ResultSet rs = stmt.executeQuery(); //This method call throws the exception