gpt4 book ai didi

java - 是否可以将 GROUP BY 与绑定(bind)变量一起使用?

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:26 26 4
gpt4 key购买 nike

我想发出如下查询

select max(col1), f(:1, col2) from t group by f(:1, col2)

其中 :1 是一个绑定(bind)变量。使用 PreparedStatement,如果我说

connection.prepareStatement
("select max(col1), f(?, col2) from t group by f(?, col2)")

我从 DBMS 得到一个错误,提示 f(?, col2) 不是 GROUP BY 表达式。

通常如何在 JDBC 中解决这个问题?

最佳答案

我建议重新编写语句,以便只有一个绑定(bind)参数。这种方法有点难看,但返回结果集:

select max(col1) 
, f_col2
from (
select col1
, f(? ,col2) as f_col2
from t
)
group
by f_col2

这个重写的语句只引用了一个绑定(bind)参数,所以现在 DBMS 认为 GROUP BY 子句和 SELECT 列表中的表达式是相同的。

HTH

[编辑]

(我希望有更漂亮的方法,这就是为什么我更喜欢 Oracle 使用的命名绑定(bind)参数方法。使用 Perl DBI 驱动程序,位置参数被转换为实际发送到 Oracle 的语句中的命名参数。)

一开始没看出问题,没看懂原题。 (显然,其他几个人也错过了它。)但是在运行一些测试用例之后,我明白了问题是什么,问题是什么在起作用。

让我看看我是否可以陈述问题:如何让两个单独的(位置)绑定(bind)参数(由 DBMS)处理,就好像它们是对相同(命名的)绑定(bind)参数的两个引用。

DBMS 期望 GROUP BY 中的表达式与 SELECT 列表中的表达式相匹配。但是这两个表达式被认为是不同的,即使这两个表达式是相同的,唯一的区别是每个表达式引用不同的绑定(bind)变量。 (我们可以演示一些至少某些 DBMS 允许的测试用例,但还有更一般的用例会引发异常。)

在这一点上,简短的回答是,这让我难住了。我的建议(可能不是对原始问题的实际答案)是重组查询。

[/编辑]

如果此方法不起作用,或者如果您在解决问题时遇到其他问题,我可以提供更多详细信息。或者如果性能有问题(我可以看到优化器为重写的查询选择了不同的计划,即使它返回了指定的结果集。为了进一步测试,我们真的需要知道什么 DBMS,什么驱动程序,统计等)

编辑(八年半后)

再次尝试重写查询。同样,我想出的唯一解决方案是使用一个绑定(bind)占位符的查询。这一次,我们将它粘贴到一个返回单行的内联 View 中,并将其连接到 t。我可以看到它在做什么;我不确定 Oracle 优化器将如何看待这一点。我们可能希望(或需要)进行显式转换,例如TO_NUMBER(?) AS paramTO_DATE(?,'...') AS paramTO_CHAR(?) AS param,取决于绑定(bind)参数的数据类型,以及我们希望从 View 返回的数据类型。)

这就是我在 MySQL 中的做法。我回答中的原始查询在内联 View (MySQL 派生表)中执行连接操作。如果可以避免,我们希望避免具体化 hughjass 派生表。话又说回来,只要 sql_mode 不包括 ONLY_FULL_GROUP_BY,MySQL 可能会让原始查询滑动。 MySQL 也会让我们删除 FROM DUAL)

  SELECT MAX(t.col1)
, f( v.param ,t.col2)
FROM t
CROSS
JOIN ( SELECT ? AS param FROM DUAL) v
GROUP
BY f( v.param ,t.col2)

根据 MadusankaD 的回答,在过去的八年中,Oracle 添加了对在 JDBC 驱动程序中重用相同命名的绑定(bind)参数的支持,并保留等价性。 (我还没有测试过,但如果现在可以,那就太好了。)

关于java - 是否可以将 GROUP BY 与绑定(bind)变量一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/941034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com