使用预准备语句的可变列名称

我想知道是否有指定使用准备语句返回的列名称。

我正在使用MySQL和Java。

当我尝试它时:

String columnNames="d,e,f"; //Actually from the user... String name = "some_table"; //From user... String query = "SELECT a,b,c,? FROM " + name + " WHERE d=?";//... stmt = conn.prepareStatement(query); stmt.setString(1, columnNames); stmt.setString(2, "x"); 

我得到这种types的声明(执行之前打印)。

 SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x' 

不过我想看看:

 SELECT a,b,c,d,e,f FROM some_table WHERE d='x' 

我知道,我不能这样做表名,正如这里所讨论的,但是想知道是否有某种方法可以对列名进行操作。

如果没有,那么我将不得不尝试确保我对input进行清理,以免导致SQL注入漏洞。

这表明一个不好的数据库devise。 用户不需要知道列名。 创build一个真正的数据库列,其中包含这些“列名”,并存储在它的数据。

不pipe怎样,不可以将列名称设置为PreparedStatement值。 您只能将列设置为PreparedStatement

如果你想继续这个方向,你需要清理列名并自己连接/构buildSQLstring。 引用单独的列名称,并使用String#replace()来转义列名内的相同引号。

准备允许列名称的白名单。 使用“查询”在白名单中查找列名是否存在。 如果不是,则拒绝查询。

我认为这种情况是行不通的,因为准备好的语句的整个目的是为了防止用户input非转义的查询位 – 所以你总是要引用或转义文本。

如果要安全地影响查询结构,则需要使用Java对input进行清理。

使用SQL注入语句接口的缺点作为优势。 例如:

 st=conn.createStatement(); String columnName="name"; rs=st.executeQuery("select "+ columnName+" from ad_org "); 

下面是java中的解决scheme。

 String strSelectString = String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName); 
 public void MethodName(String strFieldName1, String strFieldName2, String strTableName) { //Code to connect with database String strSQLQuery=String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName); st=conn.createStatement(); rs=st.executeQuery(strSQLQuery); //rest code }