【问题标题】:Cannot use bind variables in a DDL statement. Alternatives?不能在 DDL 语句中使用绑定变量。备择方案?
【发布时间】:2012-05-31 23:44:35
【问题描述】:

首先,前言:我正在编写一个java 类,它使用jdbc 在数据库上创建临时表。我使用 JSE6 和 Oracle 11XE 作为测试数据库,但该类也需要与 DB2 兼容。

我正在尝试创建的临时表来自一个更大的临时表,并且我对数据进行了一些过滤和聚合。我过滤的参数是由用户在运行时决定的。我正在尝试做的一个简化示例是:

CREATE TABLE temp_table AS (
    SELECT
           table1.department_id,
           SUM(CASE WHEN table1.number_1 < &1 THEN table1.number_1 ELSE 0 END)) AS column1              
    FROM
           table1
    GROUP BY table1.department_id
)

我的问题是我需要指定参数来过滤数据,并且我需要确保它们被正确地转义/本地化/键入。使用准备好的语句会很容易,但我不能将绑定变量与 DDL 一起使用。 我采取的临时解决方案是自己更改查询字符串,将参数写入正确的位置,但这意味着我现在必须实现所有检查,而不是依赖 PreparedStatement 对象为我做这件事,除了丢失所有其他好处。

我研究了其他解决方案,但到目前为止没有一个能说服我:

  1. 我可以先创建一个空的 temp_table,然后用 INSERT INTO temp_table(id, column1) (SELECT ...) 填充它,但似乎我可能会导致性能损失,所以我想坚持CREATE temp_table AS

  2. 我考虑过创建一个临时语句来保存内部 SELECT 查询,并让它生成格式正确/本地化/等。查询字符串,但我还没有找到任何方法从中获取最终查询(我读到它绝对不可能here)。我在这种情况下找到的唯一选择是使用DebuggableStatement,但我不确定我是否可以将它包含在项目中(另外,这似乎是解决我的问题的一种非常不雅的方式)

  3. 我正在考虑的另一个解决方案是简单地将创建临时表的查询(对于每个查询,我会将整个 CREATE AS (SELECT...)过程,然后我可以使用 CallableStatement 调用它。这样我可以避免处理类型化并且仍然具有良好的性能,但代价是与数据库更紧密的耦合(我必须确保程序在那里,或在 java 中管理它们从数据库中的添加/删除)

所以,我的问题是:有没有比我能想到的更好的选择?

【问题讨论】:

标签: java sql jdbc ddl bind-variables


【解决方案1】:

这应该与数据库无关,还是您只针对 Oracle?您不必将 PL/SQL 存储在存储过程中即可使用它;只需构建一个匿名 PL/SQL 块来执行您需要的操作,然后执行它。匿名 PL/SQL 块可以动态构建,以便在 PL/SQL 中声明强类型变量以保存您的参数,然后您的 java 代码将值粘贴进去。Java 不会处理类型安全,因为您'重新构建一个字符串;当您执行匿名 PL/SQL 块时,它将由 Oracle 处理。

【讨论】:

  • 是的,这应该与数据库无关,只有 oracle 版本是最后的手段。无论如何,我认为这正是我想要的。谢谢!
猜你喜欢
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
  • 2018-01-03
相关资源
最近更新 更多