Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将表名作为已准备语句的参数传递_Java_Mysql_Sql_Prepared Statement - Fatal编程技术网

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

我正在尝试学习如何将MySQL与Java结合使用,正如标题所说,我在准备语句时遇到了问题

我有一个名为temp的MySQL表,其中包含值(直接从MySQL控制台输出):

在Java中,我访问数据库的方式如下:

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