jdbc - CREATE USER 和 CREATE ROLE as PreparedStatement with ? 占位符
问题描述
我正在尝试以CREATE USER
允许使用参数的方式从 Java 代码中针对 HSQLDB 数据库发出语句。
但是,以下行:
connection.prepareStatement("CREATE USER ? PASSWORD ?;");
抛出异常:
java.sql.SQLSyntaxErrorException: unexpected token: ? in statement [CREATE USER ? PASSWORD ?;]
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
at (somewhere in my code)
同样的情况发生在
connection.prepareStatement("CREATE ROLE ?;");
当然,我可以?
通过将值直接粘贴到语句中来组装不带 的字符串,尽管这会为 SQL 注入带来一些可能性。
所以我想知道为什么占位符不起作用。这些声明是否完全支持它们?还是我错过了其他东西?
解决方案
一般来说,数据库只允许在 DML 中使用参数,而不是在 DDL 中。而在 DML 中,它只允许用于values。在 and 的情况下CREATE USER
,CREATE ROLE
您不处理值(至少不是用户名或角色名),因此这些参数化是不可能的。这类似于不允许在 select 语句中使用表名或列名的参数。
理论上,像密码这样的东西CREATE PASSWORD
是一个值并且可以参数化,但实际上这是不可能的(至少,我不知道),因为所有 DDL 都被处理为不可参数化。
作为一种针对 SQL 注入的次要保护形式,自 JDBC 4.3(在 Java 9 中引入)以来,您可以使用Statement.enquoteIdentifier
引用标识符以及Statement.enquoteLiteral
密码等文字。这些方法有一个默认实现,但是如果您使用的是带有非标准标识符引号的平台(例如 MySQL),那么您必须确保它实际上被覆盖(在当前版本的 MySQL Connector/ 中不是这种情况) J阿法伊克)。
推荐阅读
- python-3.x - 使用字符串切片的longestPalindromeSubstring 的时间复杂度是多少?
- java - 带有 Spring Boot 的 Microsoft Graph api 邮件服务
- jboss - JBPM_7.XX:如何将角色名称“admin”更改为其他名称?
- php - 如何在 yii2 特定目标页面中取消链接 js 文件?
- c - 如何使用 mmap 将新条目映射到用户空间内存区域,以便用户级进程可以读取和写入内核空间?
- php - 当用户使用 ajax 在 laravel 中选择任何下拉值时,如何立即显示数据库详细信息?
- javascript - 我在我的 html 画布上重绘一些圆圈时遇到问题
- android-camera - 应该使用什么颜色格式来编码媒体编解码器中libyuv转换的i420帧?
- amazon-web-services - AWS AutoScaling 组 Node.js 服务器运行状况不佳
- mysql - MySQL Sakila 数一数 Penelope Guiness 出演的电影