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

KLe*_*ee1 38 java sql jdbc prepared-statement

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

我正在使用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");
Run Code Online (Sandbox Code Playgroud)

我得到这种类型的声明(在执行之前打印).

SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'
Run Code Online (Sandbox Code Playgroud)

不过我想看到:

SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
Run Code Online (Sandbox Code Playgroud)

我知道我不能这样做表名,正如这里讨论的那样 ,但是想知道是否有某种方法可以为列名做这些.

如果没有,那么我将只需要尝试确保我清理输入,这样就不会导致SQL注入漏洞.

Bal*_*usC 35

这表明数据库设计不良.用户不需要知道列名称.创建一个真正的数据库列,其中包含这些"列名称"并将数据存储在其中.

无论如何,不​​,您不能将列名称设置为PreparedStatement值.您只能将列设置为PreparedStatement

如果您想继续这个方向,您需要清理列名并自己连接/构建SQL字符串.引用单独的列名称并使用它String#replace()来转义列名称中的相同引号.

  • 而是在服务器端处理它.不要在客户端做生意. (3认同)

小智 14

准备允许的列名称的白名单.使用"查询"查找白名单以查看列名是否存在.如果没有,请拒绝查询.


Dra*_*tin 8

接受的答案实际上并不正确。虽然 OP 方法表明数据库设计不好,但业务逻辑可能需要它(例如 MySQL IDE)

无论如何,对于 MySQL 准备好的语句,您需要知道的是?值,但是如果您需要转义列名、表名等,请??改用。

像这样的事情会起作用:

SELECT ??, ??, ?? FROM ?? WHERE ?? < ? 
Run Code Online (Sandbox Code Playgroud)

将值设置为 ['id', 'name', 'address', 'user', 'id', 100]

  • 这是一个非常有趣的评论。我找不到任何对转义参数值语法的引用(??)。您能给我指出一个吗? (2认同)
  • @YamiOdymel 事实上,这可能只适用于 mysqljs/mysql Node.js 包。从 MySQLWorkbench 运行时,该选择似乎无效。此语句不起作用,因为无法识别 `??` `PREPARE stmt1 FROM 'SELECT ??, ?? 从 ??在哪里 ??=?';设置@a = 'foo'; SET @b = '酒吧'; SET @c = 'Foos'; 设置@d = 'foo'; SET @e = 'fooooo'; 使用 @a、@b、@c、@d、@e 执行 stmt1;` (2认同)