无法在DDL语句中使用绑定变量。备择方案?

时间:2012-05-25 11:29:25

标签: java sql jdbc ddl bind-variables

首先,前言:我正在编写一个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调用。这样我可以避免处理典型化并且仍然具有良好的性能,代价是与db更紧密的耦合(我必须确保程序在那里,或在java中管理他们从数据库中添加/删除

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

1 个答案:

答案 0 :(得分:0)

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