使用 Prepared Statement 设置 LONG 数据类型
Posted
技术标签:
【中文标题】使用 Prepared Statement 设置 LONG 数据类型【英文标题】:Set LONG data type using a Prepared Statement 【发布时间】:2011-12-08 20:07:52 【问题描述】:我的情况是我需要在某些时候动态创建数据库分区。我正在使用Statement
,如下所示:
alter table table_name split partition default_partition values (' +
id + ') into ( partition " + partitionName + ", partition
default_partition) update indexes
这很好用,完全符合我的预期。但是,id
的值来自未经授权的人可能访问的输入。因此,上述语句容易受到 SQL 注入攻击。我想使用PreparedStatement
,但我不知道如何使用。
问题是oracle 中的分区表将“id
”值放入了一个LONG 的HIGH_VALUE 列。我看不到合适的设置器来执行此操作(因为 String 无法工作)。我尝试使用各种流消息,StringReader
和 ByteArrayInputStream
作为值都无济于事。我知道 LONG 不应该再使用了,但 Oracle 就是这样做的,所以我无法真正绕过它。
当我尝试使用这些方法中的任何一种时,这就是我得到的:
ORA-14308: partition bound element must be one of: string, datetime or interval literal, number, or NULL
Oracle 文档提供了有关如何获取 LONG(Oracle 数据类型,类似于 LOB)的详细信息,但没有关于如何设置它的信息。谁能帮我解决这个问题?我还研究了 JDBC 驱动程序的 Oracle 实现,但它似乎也没有 setLONG 类型的方法。有什么办法可以做到吗?
【问题讨论】:
也许我遗漏了一些东西,但我认为 PreparedStatement 上有一个名为 'setLong(int, long)' 的方法:docs.oracle.com/javase/6/docs/api/java/sql/… 那行不通吗? 是的,LONG oracle 类型基本上是一个 LOB。所以,它不像 Java 那样长。 既然Oracle的LONG是字符数据(傻瓜),你试过setString(int, id.toString())
吗?你试过什么套路?
我已经尝试了所有有意义的方法(即,不是十进制、浮点等)。所以,所有的流、字符串等。我也尝试过 CLOB/LOB/etc、char 等。使用 Oracle 特定的 impl,我尝试了 setRAW setOracleAsObject 和其他一些但没有成功。对我来说,Oracle 建议不要使用 LONG 似乎太疯狂了,然后继续使用它,同时让它难以使用,呵呵。
【参考方案1】:
您不能将绑定变量与 DDL 一起使用。您将无法在 DDL 语句中使用 PreparedStatement
和调用任何 setXXXX
方法。
根据用户输入动态拆分分区至少是一种非常不寻常的设计。我倾向于怀疑像interval partitioning 这样的东西会更好地为您服务,Oracle 在需要时负责创建新分区或散列分区而不是范围分区。假设动态手动创建新分区确实有意义,但是,您必须编写代码来验证“id”和“partitionName”值是否有效,以防止 SQL 注入。
【讨论】:
好吧,我只是想简化一些事情。不是任何用户都可以做到这一点。它将受到很大限制,但我们仍然希望确保我们受到保护,以防少数用户变得腐烂或有人以其他方式获得访问权限。我将使用验证路线,即使它不是 PS 的保证。谢谢。【参考方案2】:id是String吗,如果是,为什么不先验证一下?
try
id = Long.valueOf(unsafeId);
//do more validations here
catch (NumberFormatException e)
throw new RuntimeException("Not a valid input.");
【讨论】:
它实际上不是一个 Long。 db中的类型是LONG,实际上只是char数据。此外,有效 id 可以采用的形式是多种多样的(并且 id 是一个坏名字,我用它替换了实际名称只是为了举例)。以上是关于使用 Prepared Statement 设置 LONG 数据类型的主要内容,如果未能解决你的问题,请参考以下文章
如何在SELECT FROM PDO Prepared Statement中为搜索框设置多个搜索条件?
当 Statement 与 Java 和 Oracle 一起使用时,Prepared Statement 不起作用
MYSQLI Prepared statement update statement with where in array
Java 和 Access - 使用 Prepared Statement 并获取日期