使用 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 无法工作)。我尝试使用各种流消息,StringReaderByteArrayInputStream 作为值都无济于事。我知道 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 并获取日期

使用 Prepared Statement,我如何返回插入行的 id?

未找到 Java Prepared statement 错误表